nextworks 0.2.0-alpha.2 → 0.2.0-alpha.20

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 (145) hide show
  1. package/README.md +280 -228
  2. package/dist/cli_manifests/blocks_manifest.json +193 -194
  3. package/dist/commands/blocks.d.ts +3 -0
  4. package/dist/commands/blocks.d.ts.map +1 -1
  5. package/dist/commands/blocks.js +128 -19
  6. package/dist/commands/blocks.js.map +1 -1
  7. package/dist/commands/doctor.d.ts +136 -0
  8. package/dist/commands/doctor.d.ts.map +1 -0
  9. package/dist/commands/doctor.js +696 -0
  10. package/dist/commands/doctor.js.map +1 -0
  11. package/dist/commands/remove-blocks.d.ts +4 -1
  12. package/dist/commands/remove-blocks.d.ts.map +1 -1
  13. package/dist/commands/remove-blocks.js +24 -6
  14. package/dist/commands/remove-blocks.js.map +1 -1
  15. package/dist/index.js +125 -4
  16. package/dist/index.js.map +1 -1
  17. package/dist/kits/blocks/.nextworks/docs/BLOCKS_QUICKSTART.md +104 -194
  18. package/dist/kits/blocks/.nextworks/docs/BLOCKS_README.md +115 -75
  19. package/dist/kits/blocks/.nextworks/docs/THEME_GUIDE.md +269 -251
  20. package/dist/kits/blocks/app/templates/digitalagency/PresetThemeVars.tsx +80 -80
  21. package/dist/kits/blocks/app/templates/digitalagency/README.md +42 -36
  22. package/dist/kits/blocks/app/templates/digitalagency/components/About.tsx +71 -99
  23. package/dist/kits/blocks/app/templates/digitalagency/components/CTA.tsx +40 -74
  24. package/dist/kits/blocks/app/templates/digitalagency/components/Contact.tsx +123 -227
  25. package/dist/kits/blocks/app/templates/digitalagency/components/Footer.tsx +89 -89
  26. package/dist/kits/blocks/app/templates/digitalagency/components/Hero.tsx +83 -90
  27. package/dist/kits/blocks/app/templates/digitalagency/components/Navbar.tsx +121 -168
  28. package/dist/kits/blocks/app/templates/digitalagency/components/NetworkPattern.tsx +288 -297
  29. package/dist/kits/blocks/app/templates/digitalagency/components/Portfolio.tsx +157 -157
  30. package/dist/kits/blocks/app/templates/digitalagency/components/Pricing.tsx +114 -114
  31. package/dist/kits/blocks/app/templates/digitalagency/components/Process.tsx +59 -59
  32. package/dist/kits/blocks/app/templates/digitalagency/components/Services.tsx +55 -55
  33. package/dist/kits/blocks/app/templates/digitalagency/components/Team.tsx +28 -28
  34. package/dist/kits/blocks/app/templates/digitalagency/components/Testimonials.tsx +65 -65
  35. package/dist/kits/blocks/app/templates/digitalagency/page.tsx +38 -38
  36. package/dist/kits/blocks/app/templates/gallery/PresetThemeVars.tsx +130 -85
  37. package/dist/kits/blocks/app/templates/gallery/page.tsx +357 -303
  38. package/dist/kits/blocks/app/templates/productlaunch/PresetThemeVars.tsx +75 -74
  39. package/dist/kits/blocks/app/templates/productlaunch/README.md +62 -55
  40. package/dist/kits/blocks/app/templates/productlaunch/components/About.tsx +84 -178
  41. package/dist/kits/blocks/app/templates/productlaunch/components/CTA.tsx +50 -93
  42. package/dist/kits/blocks/app/templates/productlaunch/components/Contact.tsx +231 -231
  43. package/dist/kits/blocks/app/templates/productlaunch/components/FAQ.tsx +86 -93
  44. package/dist/kits/blocks/app/templates/productlaunch/components/Features.tsx +83 -84
  45. package/dist/kits/blocks/app/templates/productlaunch/components/Footer.tsx +132 -132
  46. package/dist/kits/blocks/app/templates/productlaunch/components/Hero.tsx +88 -89
  47. package/dist/kits/blocks/app/templates/productlaunch/components/Navbar.tsx +116 -162
  48. package/dist/kits/blocks/app/templates/productlaunch/components/Pricing.tsx +106 -106
  49. package/dist/kits/blocks/app/templates/productlaunch/components/ProcessTimeline.tsx +110 -110
  50. package/dist/kits/blocks/app/templates/productlaunch/components/ServicesGrid.tsx +68 -68
  51. package/dist/kits/blocks/app/templates/productlaunch/components/Team.tsx +104 -104
  52. package/dist/kits/blocks/app/templates/productlaunch/components/Testimonials.tsx +90 -89
  53. package/dist/kits/blocks/app/templates/productlaunch/components/TrustBadges.tsx +76 -76
  54. package/dist/kits/blocks/app/templates/productlaunch/page.tsx +43 -43
  55. package/dist/kits/blocks/app/templates/saasdashboard/PresetThemeVars.tsx +80 -80
  56. package/dist/kits/blocks/app/templates/saasdashboard/README.md +44 -38
  57. package/dist/kits/blocks/app/templates/saasdashboard/components/Contact.tsx +129 -176
  58. package/dist/kits/blocks/app/templates/saasdashboard/components/Dashboard.tsx +293 -293
  59. package/dist/kits/blocks/app/templates/saasdashboard/components/FAQ.tsx +55 -55
  60. package/dist/kits/blocks/app/templates/saasdashboard/components/Features.tsx +90 -91
  61. package/dist/kits/blocks/app/templates/saasdashboard/components/Footer.tsx +77 -77
  62. package/dist/kits/blocks/app/templates/saasdashboard/components/Hero.tsx +104 -105
  63. package/dist/kits/blocks/app/templates/saasdashboard/components/Hero_mask.tsx +126 -127
  64. package/dist/kits/blocks/app/templates/saasdashboard/components/Navbar.tsx +117 -159
  65. package/dist/kits/blocks/app/templates/saasdashboard/components/Pricing.tsx +90 -90
  66. package/dist/kits/blocks/app/templates/saasdashboard/components/SmoothScroll.tsx +96 -97
  67. package/dist/kits/blocks/app/templates/saasdashboard/components/Testimonials.tsx +72 -72
  68. package/dist/kits/blocks/app/templates/saasdashboard/components/TrustBadges.tsx +53 -53
  69. package/dist/kits/blocks/app/templates/saasdashboard/page.tsx +39 -39
  70. package/dist/kits/blocks/components/enhanced-theme-provider.tsx +195 -183
  71. package/dist/kits/blocks/components/providers/BlocksAppProviders.tsx +27 -27
  72. package/dist/kits/blocks/components/sections/About.tsx +291 -291
  73. package/dist/kits/blocks/components/sections/CTA.tsx +257 -258
  74. package/dist/kits/blocks/components/sections/CommandShowcase.tsx +517 -0
  75. package/dist/kits/blocks/components/sections/Contact.tsx +267 -267
  76. package/dist/kits/blocks/components/sections/FAQ.tsx +214 -225
  77. package/dist/kits/blocks/components/sections/FeaturedProjectShowcase.tsx +687 -0
  78. package/dist/kits/blocks/components/sections/Features.tsx +268 -270
  79. package/dist/kits/blocks/components/sections/Footer.tsx +302 -302
  80. package/dist/kits/blocks/components/sections/HeroMotion.tsx +308 -308
  81. package/dist/kits/blocks/components/sections/HeroOverlay.tsx +358 -358
  82. package/dist/kits/blocks/components/sections/HeroProductDemo.tsx +246 -0
  83. package/dist/kits/blocks/components/sections/HeroSplit.tsx +352 -352
  84. package/dist/kits/blocks/components/sections/HeroWithVideo.tsx +495 -0
  85. package/dist/kits/blocks/components/sections/Navbar.tsx +352 -353
  86. package/dist/kits/blocks/components/sections/PortfolioSimple.tsx +549 -550
  87. package/dist/kits/blocks/components/sections/Pricing.tsx +264 -264
  88. package/dist/kits/blocks/components/sections/ProcessTimeline.tsx +325 -325
  89. package/dist/kits/blocks/components/sections/ProjectDeepDive.tsx +805 -0
  90. package/dist/kits/blocks/components/sections/SelectedWorkRail.tsx +485 -0
  91. package/dist/kits/blocks/components/sections/ServicesGrid.tsx +210 -210
  92. package/dist/kits/blocks/components/sections/Team.tsx +309 -309
  93. package/dist/kits/blocks/components/sections/Testimonials.tsx +158 -158
  94. package/dist/kits/blocks/components/sections/TrustBadges.tsx +162 -162
  95. package/dist/kits/blocks/components/sections/product-demo/ApprovalInboxPanel.tsx +128 -0
  96. package/dist/kits/blocks/components/sections/product-demo/DemoStage.tsx +519 -0
  97. package/dist/kits/blocks/components/sections/product-demo/DemoWindow.tsx +140 -0
  98. package/dist/kits/blocks/components/sections/product-demo/KnowledgePanel.tsx +130 -0
  99. package/dist/kits/blocks/components/sections/product-demo/RunConsolePanel.tsx +430 -0
  100. package/dist/kits/blocks/components/sections/product-demo/TaskListPanel.tsx +302 -0
  101. package/dist/kits/blocks/components/sections/product-demo/WorkflowStudioPanel.tsx +744 -0
  102. package/dist/kits/blocks/components/sections/product-demo/types.ts +262 -0
  103. package/dist/kits/blocks/components/theme-provider.tsx +1 -34
  104. package/dist/kits/blocks/components/ui/alert-dialog.tsx +134 -134
  105. package/dist/kits/blocks/components/ui/brand-node.tsx +121 -121
  106. package/dist/kits/blocks/components/ui/button.tsx +122 -122
  107. package/dist/kits/blocks/components/ui/card.tsx +95 -95
  108. package/dist/kits/blocks/components/ui/checkbox.tsx +30 -30
  109. package/dist/kits/blocks/components/ui/cta-button.tsx +125 -125
  110. package/dist/kits/blocks/components/ui/dropdown-menu.tsx +201 -201
  111. package/dist/kits/blocks/components/ui/feature-card.tsx +91 -91
  112. package/dist/kits/blocks/components/ui/input.tsx +27 -27
  113. package/dist/kits/blocks/components/ui/label.tsx +29 -29
  114. package/dist/kits/blocks/components/ui/pricing-card.tsx +120 -120
  115. package/dist/kits/blocks/components/ui/select.tsx +25 -25
  116. package/dist/kits/blocks/components/ui/skeleton.tsx +13 -13
  117. package/dist/kits/blocks/components/ui/table.tsx +98 -98
  118. package/dist/kits/blocks/components/ui/testimonial-card.tsx +108 -108
  119. package/dist/kits/blocks/components/ui/textarea.tsx +26 -26
  120. package/dist/kits/blocks/components/ui/theme-selector.tsx +243 -247
  121. package/dist/kits/blocks/components/ui/theme-toggle.tsx +74 -74
  122. package/dist/kits/blocks/components/ui/toaster.tsx +7 -7
  123. package/dist/kits/blocks/lib/themes.ts +400 -400
  124. package/dist/kits/blocks/lib/utils.ts +6 -9
  125. package/dist/kits/blocks/package-deps.json +40 -28
  126. package/dist/kits/blocks/tsconfig.json +11 -0
  127. package/dist/kits/blocks/tsconfig.tsbuildinfo +1 -0
  128. package/dist/utils/file-operations.d.ts +3 -1
  129. package/dist/utils/file-operations.d.ts.map +1 -1
  130. package/dist/utils/file-operations.js +84 -12
  131. package/dist/utils/file-operations.js.map +1 -1
  132. package/dist/utils/installation-tracker.d.ts +2 -2
  133. package/dist/utils/installation-tracker.d.ts.map +1 -1
  134. package/dist/utils/installation-tracker.js +11 -11
  135. package/dist/utils/installation-tracker.js.map +1 -1
  136. package/dist/utils/package-manager.d.ts +6 -0
  137. package/dist/utils/package-manager.d.ts.map +1 -0
  138. package/dist/utils/package-manager.js +58 -0
  139. package/dist/utils/package-manager.js.map +1 -0
  140. package/dist/utils/yarn-pnp.d.ts +6 -0
  141. package/dist/utils/yarn-pnp.d.ts.map +1 -0
  142. package/dist/utils/yarn-pnp.js +39 -0
  143. package/dist/utils/yarn-pnp.js.map +1 -0
  144. package/package.json +5 -2
  145. package/dist/kits/blocks/notes/THEME_GUIDE.md +0 -29
@@ -0,0 +1,696 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.doctor = doctor;
7
+ exports.formatDoctorResult = formatDoctorResult;
8
+ const fs_extra_1 = __importDefault(require("fs-extra"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const file_operations_1 = require("../utils/file-operations");
11
+ const package_manager_1 = require("../utils/package-manager");
12
+ const yarn_pnp_1 = require("../utils/yarn-pnp");
13
+ const installation_tracker_1 = require("../utils/installation-tracker");
14
+ const TEMPLATE_SLUGS = [
15
+ "productlaunch",
16
+ "saasdashboard",
17
+ "digitalagency",
18
+ "gallery",
19
+ ];
20
+ const COLLISION_CANDIDATES = {
21
+ src: [
22
+ "src/components/app-providers.tsx",
23
+ "src/components/ui",
24
+ "src/components/sections",
25
+ "src/app/globals.css",
26
+ "src/app/tw-animate.css",
27
+ "src/lib/utils.ts",
28
+ "src/app/layout.tsx",
29
+ "src/pages/_app.tsx",
30
+ "src/pages/_document.tsx",
31
+ ],
32
+ root: [
33
+ "components/app-providers.tsx",
34
+ "components/ui",
35
+ "components/sections",
36
+ "app/globals.css",
37
+ "app/tw-animate.css",
38
+ "lib/utils.ts",
39
+ "app/layout.tsx",
40
+ "pages/_app.tsx",
41
+ "pages/_document.tsx",
42
+ ],
43
+ };
44
+ function hasTailwindDependency(pkg) {
45
+ return Boolean(pkg.dependencies?.tailwindcss || pkg.devDependencies?.tailwindcss);
46
+ }
47
+ function hasTypeScriptDependency(pkg) {
48
+ return Boolean(pkg.dependencies?.typescript || pkg.devDependencies?.typescript);
49
+ }
50
+ async function hasTsconfig(cwd) {
51
+ return (0, file_operations_1.fileExists)(path_1.default.join(cwd, "tsconfig.json"));
52
+ }
53
+ async function hasCssBasedTailwindUsage(cwd) {
54
+ const cssCandidates = [
55
+ path_1.default.join(cwd, "app", "globals.css"),
56
+ path_1.default.join(cwd, "src", "app", "globals.css"),
57
+ path_1.default.join(cwd, "styles", "globals.css"),
58
+ path_1.default.join(cwd, "src", "styles", "globals.css"),
59
+ path_1.default.join(cwd, "pages", "_app.tsx"),
60
+ path_1.default.join(cwd, "src", "pages", "_app.tsx"),
61
+ ];
62
+ for (const candidate of cssCandidates) {
63
+ if (!(await (0, file_operations_1.fileExists)(candidate))) {
64
+ continue;
65
+ }
66
+ try {
67
+ const content = await fs_extra_1.default.readFile(candidate, "utf8");
68
+ if (content.includes('@import "tailwindcss"') ||
69
+ content.includes("@import 'tailwindcss'") ||
70
+ content.includes("@theme")) {
71
+ return true;
72
+ }
73
+ }
74
+ catch {
75
+ continue;
76
+ }
77
+ }
78
+ return false;
79
+ }
80
+ const MIN_MAJOR_NODE_VERSION = 20;
81
+ const YARN_PNP_MESSAGE = "Set nodeLinker: node-modules in .yarnrc.yml";
82
+ function createInitialDoctorResult() {
83
+ return {
84
+ projectSanity: {
85
+ hasPackageJson: false,
86
+ hasNext: false,
87
+ projectRoot: null,
88
+ routerType: null,
89
+ projectRootMode: null,
90
+ },
91
+ environmentChecks: {
92
+ nodeVersion: { status: "ok", message: "" },
93
+ packageManager: { pm: "pnpm", installCommand: "" },
94
+ yarnPnPDetection: {
95
+ isPnP: false,
96
+ message: YARN_PNP_MESSAGE,
97
+ },
98
+ tailwind: {
99
+ hasTailwindDependency: false,
100
+ hasCssBasedTailwindUsage: false,
101
+ detected: false,
102
+ },
103
+ typescript: {
104
+ hasTsconfig: false,
105
+ hasTypeScriptDependency: false,
106
+ detected: false,
107
+ },
108
+ },
109
+ projectRootWritability: {
110
+ path: "",
111
+ exists: false,
112
+ writable: null,
113
+ },
114
+ appProvidersShim: {
115
+ path: "",
116
+ exists: false,
117
+ target: null,
118
+ targetExists: null,
119
+ targetMatchesRouter: null,
120
+ },
121
+ collisions: {
122
+ paths: [],
123
+ },
124
+ recordedInstallState: {
125
+ installedKits: [],
126
+ },
127
+ blocksFilePresence: [],
128
+ routerPatchability: {
129
+ appLayout: {
130
+ path: "",
131
+ exists: false,
132
+ writable: false,
133
+ writableInfo: { status: "init" },
134
+ hasSuppressHydrationWarning: { status: "init" },
135
+ },
136
+ pagesApp: {
137
+ path: "",
138
+ exists: false,
139
+ writable: false,
140
+ writableInfo: { status: "init" },
141
+ hasSuppressHydrationWarning: { status: "init" },
142
+ },
143
+ pagesDocument: {
144
+ path: "",
145
+ exists: false,
146
+ writable: false,
147
+ writableInfo: { status: "init" },
148
+ hasSuppressHydrationWarning: { status: "init" },
149
+ },
150
+ },
151
+ warnings: [],
152
+ errors: [],
153
+ };
154
+ }
155
+ function getPackageJsonPath(cwd) {
156
+ return path_1.default.join(cwd, "package.json");
157
+ }
158
+ async function readPackageJson(cwd) {
159
+ return fs_extra_1.default.readJson(getPackageJsonPath(cwd));
160
+ }
161
+ function getNodeVersionCheck() {
162
+ const rawVersion = process.version;
163
+ const nodeVersion = process.versions.node;
164
+ const major = Number(nodeVersion.split(".")[0]);
165
+ if (!Number.isFinite(major)) {
166
+ return {
167
+ status: "error",
168
+ message: `Unable to determine Node.js version (reported: ${rawVersion})`,
169
+ };
170
+ }
171
+ if (major < MIN_MAJOR_NODE_VERSION) {
172
+ return {
173
+ status: "error",
174
+ message: `Node.js ${rawVersion} detected — nextworks requires Node.js >= ${MIN_MAJOR_NODE_VERSION}`,
175
+ };
176
+ }
177
+ return {
178
+ status: "ok",
179
+ message: `Node.js ${rawVersion} detected`,
180
+ };
181
+ }
182
+ function getProjectRootInfo(options) {
183
+ const { mode, hasAppRouter, hasPagesRouter } = options;
184
+ if (mode !== "src" && mode !== "root") {
185
+ return {
186
+ routerType: null,
187
+ projectRootMode: null,
188
+ };
189
+ }
190
+ let routerType = null;
191
+ let routerTypeLabel = null;
192
+ if (hasAppRouter && hasPagesRouter) {
193
+ routerType = "hybrid";
194
+ routerTypeLabel = "Hybrid router";
195
+ }
196
+ else if (hasAppRouter) {
197
+ routerType = "app";
198
+ routerTypeLabel = "App router";
199
+ }
200
+ else if (hasPagesRouter) {
201
+ routerType = "pages";
202
+ routerTypeLabel = "Pages router";
203
+ }
204
+ else {
205
+ return {
206
+ routerType: null,
207
+ projectRootMode: null,
208
+ };
209
+ }
210
+ const rootLabel = mode === "src" ? "with src folder" : "with no src folder";
211
+ return {
212
+ routerType,
213
+ projectRootMode: `${routerTypeLabel} ${rootLabel}`,
214
+ };
215
+ }
216
+ async function fileHasSuppressHydrationWarning(filePath) {
217
+ try {
218
+ const fileContent = await fs_extra_1.default.readFile(filePath, "utf8");
219
+ return fileContent.includes("suppressHydrationWarning")
220
+ ? { status: "found" }
221
+ : { status: "not-found" };
222
+ }
223
+ catch (error) {
224
+ return { status: "unreadable", error };
225
+ }
226
+ }
227
+ async function fileIsWritable(filePath) {
228
+ try {
229
+ await fs_extra_1.default.access(filePath, fs_extra_1.default.constants.W_OK);
230
+ return { status: "writable" };
231
+ }
232
+ catch (err) {
233
+ const errorCode = typeof err === "object" &&
234
+ err !== null &&
235
+ "code" in err &&
236
+ typeof err.code === "string"
237
+ ? err.code
238
+ : null;
239
+ if (errorCode === "EACCES" || errorCode === "EPERM") {
240
+ return { status: "not-writable" };
241
+ }
242
+ const parentDir = path_1.default.dirname(filePath);
243
+ try {
244
+ await fs_extra_1.default.access(parentDir, fs_extra_1.default.constants.W_OK);
245
+ return { status: "not-found-parent-writable" };
246
+ }
247
+ catch {
248
+ return { status: "not-found-parent-not-writable" };
249
+ }
250
+ }
251
+ }
252
+ async function directoryIsWritable(directoryPath) {
253
+ try {
254
+ const stats = await fs_extra_1.default.stat(directoryPath);
255
+ if (!stats.isDirectory()) {
256
+ return null;
257
+ }
258
+ await fs_extra_1.default.access(directoryPath, fs_extra_1.default.constants.W_OK);
259
+ return true;
260
+ }
261
+ catch (error) {
262
+ if (typeof error === "object" &&
263
+ error !== null &&
264
+ "code" in error &&
265
+ (error.code === "EACCES" || error.code === "EPERM")) {
266
+ return false;
267
+ }
268
+ return null;
269
+ }
270
+ }
271
+ async function getProjectRootWritability(cwd) {
272
+ const exists = await (0, file_operations_1.fileExists)(cwd);
273
+ if (!exists) {
274
+ return {
275
+ path: cwd,
276
+ exists: false,
277
+ writable: null,
278
+ };
279
+ }
280
+ return {
281
+ path: cwd,
282
+ exists: true,
283
+ writable: await directoryIsWritable(cwd),
284
+ };
285
+ }
286
+ async function getAppProvidersShimDiagnostics(cwd, routerType) {
287
+ const warnings = [];
288
+ const shimCandidates = [
289
+ path_1.default.join(cwd, "components", "app-providers.tsx"),
290
+ path_1.default.join(cwd, "src", "components", "app-providers.tsx"),
291
+ ];
292
+ let shimPath = shimCandidates[0];
293
+ for (const candidate of shimCandidates) {
294
+ if (await (0, file_operations_1.fileExists)(candidate)) {
295
+ shimPath = candidate;
296
+ break;
297
+ }
298
+ }
299
+ const exists = await (0, file_operations_1.fileExists)(shimPath);
300
+ const shim = {
301
+ path: shimPath,
302
+ exists,
303
+ target: null,
304
+ targetExists: null,
305
+ targetMatchesRouter: null,
306
+ };
307
+ if (!exists) {
308
+ return { shim, warnings };
309
+ }
310
+ const content = await fs_extra_1.default.readFile(shimPath, "utf8");
311
+ const match = content.match(/from\s+["']\.\/(app-providers\.(?:app|pages))["']/);
312
+ const target = match?.[1] ?? null;
313
+ shim.target = target;
314
+ if (!target) {
315
+ return { shim, warnings };
316
+ }
317
+ const targetPath = path_1.default.join(path_1.default.dirname(shimPath), `${target}.tsx`);
318
+ shim.targetExists = await (0, file_operations_1.fileExists)(targetPath);
319
+ if (shim.targetExists === false) {
320
+ warnings.push(`app-providers shim target file is missing: ${targetPath}`);
321
+ }
322
+ const expectedTarget = routerType === "app"
323
+ ? "app-providers.app"
324
+ : routerType === "pages"
325
+ ? "app-providers.pages"
326
+ : null;
327
+ shim.targetMatchesRouter = expectedTarget ? expectedTarget === target : null;
328
+ if (expectedTarget && expectedTarget !== target) {
329
+ warnings.push(`app-providers shim target does not match detected ${routerType} router mode: ${shimPath} -> ${target}`);
330
+ }
331
+ return { shim, warnings };
332
+ }
333
+ function getRouterPatchabilityDiagnostics(result) {
334
+ const warnings = [];
335
+ const errors = [];
336
+ const { routerType } = result.projectSanity;
337
+ if (routerType === "app" || routerType === "hybrid") {
338
+ const appLayout = result.routerPatchability.appLayout;
339
+ if (appLayout.exists && appLayout.writableInfo.status === "not-writable") {
340
+ errors.push(`App Router layout is not writable: ${appLayout.path}`);
341
+ }
342
+ if (appLayout.exists &&
343
+ appLayout.hasSuppressHydrationWarning.status === "not-found") {
344
+ warnings.push(`App Router layout is missing suppressHydrationWarning: ${appLayout.path}`);
345
+ }
346
+ }
347
+ if (routerType === "pages" || routerType === "hybrid") {
348
+ const pagesApp = result.routerPatchability.pagesApp;
349
+ const pagesDocument = result.routerPatchability.pagesDocument;
350
+ if (pagesApp.exists && pagesApp.writableInfo.status === "not-writable") {
351
+ errors.push(`Pages Router _app.tsx is not writable: ${pagesApp.path}`);
352
+ }
353
+ if (pagesDocument.exists &&
354
+ pagesDocument.writableInfo.status === "not-writable") {
355
+ errors.push(`Pages Router _document.tsx is not writable: ${pagesDocument.path}`);
356
+ }
357
+ if (pagesDocument.exists &&
358
+ pagesDocument.hasSuppressHydrationWarning.status === "not-found") {
359
+ warnings.push(`Pages Router _document.tsx is missing suppressHydrationWarning: ${pagesDocument.path}`);
360
+ }
361
+ if (!pagesDocument.exists &&
362
+ pagesDocument.writableInfo.status === "not-found-parent-writable") {
363
+ warnings.push(`Pages Router _document.tsx does not exist and will need to be created during install: ${pagesDocument.path}`);
364
+ }
365
+ if (!pagesDocument.exists &&
366
+ pagesDocument.writableInfo.status === "not-found-parent-not-writable") {
367
+ errors.push(`Pages Router _document.tsx does not exist and its parent directory is not writable: ${pagesDocument.path}`);
368
+ }
369
+ }
370
+ return { warnings, errors };
371
+ }
372
+ function collectCollisionChecks(cwd, mode, routerType) {
373
+ const candidates = [...COLLISION_CANDIDATES[mode]];
374
+ for (const slug of TEMPLATE_SLUGS) {
375
+ if (routerType === "pages" || routerType === "hybrid") {
376
+ if (mode === "src") {
377
+ candidates.push(`src/pages/templates/${slug}/index.tsx`);
378
+ candidates.push(`src/components/templates/${slug}`);
379
+ }
380
+ else {
381
+ candidates.push(`pages/templates/${slug}/index.tsx`);
382
+ candidates.push(`components/templates/${slug}`);
383
+ }
384
+ }
385
+ if (routerType === "app" || routerType === "hybrid") {
386
+ if (mode === "src") {
387
+ candidates.push(`src/app/templates/${slug}/page.tsx`);
388
+ candidates.push(`src/app/templates/${slug}`);
389
+ }
390
+ else {
391
+ candidates.push(`app/templates/${slug}/page.tsx`);
392
+ candidates.push(`app/templates/${slug}`);
393
+ }
394
+ }
395
+ }
396
+ return candidates.map((relativePath) => ({
397
+ path: path_1.default.join(cwd, relativePath),
398
+ exists: false,
399
+ }));
400
+ }
401
+ async function getCollisionDiagnostics(cwd, mode, routerType) {
402
+ const paths = collectCollisionChecks(cwd, mode, routerType);
403
+ for (const entry of paths) {
404
+ entry.exists = await (0, file_operations_1.fileExists)(entry.path);
405
+ }
406
+ return { paths };
407
+ }
408
+ async function getRecordedInstallState() {
409
+ const config = await (0, installation_tracker_1.getNextworksConfig)();
410
+ return {
411
+ installedKits: config.installedKits.map((kit) => ({
412
+ name: kit.name,
413
+ dependencies: [...kit.dependencies],
414
+ devDependencies: [...kit.devDependencies],
415
+ files: [...kit.files],
416
+ installedAt: kit.installedAt,
417
+ })),
418
+ };
419
+ }
420
+ function getBlocksInstalledFileChecks(cwd, manifest, recordedInstallState) {
421
+ const installedBlocksKit = recordedInstallState.installedKits.find((kit) => kit.name === manifest.name);
422
+ if (!installedBlocksKit) {
423
+ return [];
424
+ }
425
+ return installedBlocksKit.files.map((relativePath) => ({
426
+ path: path_1.default.join(cwd, relativePath),
427
+ exists: false,
428
+ required: true,
429
+ }));
430
+ }
431
+ async function doctor(options = {}) {
432
+ const cwd = process.cwd();
433
+ const result = createInitialDoctorResult();
434
+ const manifestPath = (0, file_operations_1.resolveAssetPath)("cli_manifests", "blocks_manifest.json");
435
+ const packageJsonPath = getPackageJsonPath(cwd);
436
+ const hasPackageJson = await (0, file_operations_1.fileExists)(packageJsonPath);
437
+ result.projectSanity.hasPackageJson = hasPackageJson;
438
+ if (!hasPackageJson) {
439
+ result.errors.push("package.json not found. Run nextworks from a Next.js project root.");
440
+ }
441
+ let packageJson = null;
442
+ if (hasPackageJson) {
443
+ const pkg = (await readPackageJson(cwd));
444
+ packageJson = pkg;
445
+ result.projectSanity.hasNext = Boolean(pkg.dependencies?.next || pkg.devDependencies?.next);
446
+ if (!result.projectSanity.hasNext) {
447
+ result.errors.push('Next.js dependency "next" not found in dependencies or devDependencies.');
448
+ }
449
+ }
450
+ const manifest = (await (0, file_operations_1.readJsonFile)(manifestPath));
451
+ const mode = await (0, file_operations_1.detectProjectRootMode)(cwd);
452
+ result.projectSanity.projectRoot = mode;
453
+ const detectedLayoutPath = mode === "src" ? "src/app/layout.tsx" : "app/layout.tsx";
454
+ const detectedPagesAppPath = mode === "src" ? "src/pages/_app.tsx" : "pages/_app.tsx";
455
+ const appRouterLayoutExists = await (0, file_operations_1.fileExists)(detectedLayoutPath);
456
+ const pagesRouterAppExists = await (0, file_operations_1.fileExists)(detectedPagesAppPath);
457
+ const { routerType, projectRootMode } = getProjectRootInfo({
458
+ mode,
459
+ hasAppRouter: appRouterLayoutExists,
460
+ hasPagesRouter: pagesRouterAppExists,
461
+ });
462
+ if (routerType) {
463
+ result.projectSanity.routerType = routerType;
464
+ }
465
+ if (projectRootMode) {
466
+ result.projectSanity.projectRootMode = projectRootMode;
467
+ }
468
+ else {
469
+ result.errors.push("No supported Next.js router entrypoint found. Expected app/layout.tsx, src/app/layout.tsx, pages/_app.tsx, or src/pages/_app.tsx.");
470
+ }
471
+ result.environmentChecks.nodeVersion = getNodeVersionCheck();
472
+ if (result.environmentChecks.nodeVersion.status === "error") {
473
+ result.errors.push(result.environmentChecks.nodeVersion.message);
474
+ }
475
+ const detectedPM = await (0, package_manager_1.detectPackageManager)(cwd);
476
+ const installCmd = (0, package_manager_1.getInstallCommand)(detectedPM);
477
+ result.environmentChecks.packageManager.pm = detectedPM;
478
+ result.environmentChecks.packageManager.installCommand = installCmd;
479
+ const isYarnPnP = await (0, yarn_pnp_1.isYarnPnPProject)(cwd);
480
+ result.environmentChecks.yarnPnPDetection.isPnP = isYarnPnP;
481
+ if (isYarnPnP) {
482
+ result.warnings.push(`Yarn Plug'n'Play detected. ${result.environmentChecks.yarnPnPDetection.message}`);
483
+ }
484
+ if (packageJson) {
485
+ result.environmentChecks.tailwind.hasTailwindDependency =
486
+ hasTailwindDependency(packageJson);
487
+ result.environmentChecks.typescript.hasTypeScriptDependency =
488
+ hasTypeScriptDependency(packageJson);
489
+ }
490
+ result.environmentChecks.tailwind.hasCssBasedTailwindUsage =
491
+ await hasCssBasedTailwindUsage(cwd);
492
+ result.environmentChecks.tailwind.detected =
493
+ result.environmentChecks.tailwind.hasTailwindDependency ||
494
+ result.environmentChecks.tailwind.hasCssBasedTailwindUsage;
495
+ if (!result.environmentChecks.tailwind.detected) {
496
+ result.warnings.push('Tailwind CSS was not detected. Blocks requires Tailwind CSS v4-style setup via a `tailwindcss` dependency or CSS imports such as `@import "tailwindcss"`.');
497
+ }
498
+ result.environmentChecks.typescript.hasTsconfig = await hasTsconfig(cwd);
499
+ result.environmentChecks.typescript.detected =
500
+ result.environmentChecks.typescript.hasTsconfig ||
501
+ result.environmentChecks.typescript.hasTypeScriptDependency;
502
+ if (!result.environmentChecks.typescript.detected) {
503
+ result.errors.push("TypeScript was not detected. Blocks requires a `tsconfig.json` file or a `typescript` dependency in dependencies or devDependencies.");
504
+ }
505
+ result.projectRootWritability = await getProjectRootWritability(cwd);
506
+ if (!result.projectRootWritability.exists) {
507
+ result.errors.push(`Project root does not exist: ${result.projectRootWritability.path}`);
508
+ }
509
+ else if (result.projectRootWritability.writable === false) {
510
+ result.errors.push(`Project root is not writable: ${result.projectRootWritability.path}`);
511
+ }
512
+ if (result.projectSanity.routerType === "app" ||
513
+ result.projectSanity.routerType === "hybrid") {
514
+ let layoutFilePath = "";
515
+ if (result.projectSanity.projectRoot === "src") {
516
+ layoutFilePath = path_1.default.join(process.cwd(), "src", "app", "layout.tsx");
517
+ }
518
+ else {
519
+ layoutFilePath = path_1.default.join(process.cwd(), "app", "layout.tsx");
520
+ }
521
+ result.routerPatchability.appLayout.path = layoutFilePath;
522
+ const layoutExists = await (0, file_operations_1.fileExists)(layoutFilePath);
523
+ result.routerPatchability.appLayout.exists = layoutExists;
524
+ const writableInfo = await fileIsWritable(layoutFilePath);
525
+ result.routerPatchability.appLayout.writableInfo = writableInfo;
526
+ const writableStatus = writableInfo.status;
527
+ if (writableStatus === "writable") {
528
+ result.routerPatchability.appLayout.writable = true;
529
+ }
530
+ else if (writableStatus === "not-writable") {
531
+ result.routerPatchability.appLayout.writable = false;
532
+ }
533
+ else {
534
+ result.routerPatchability.appLayout.writable = null;
535
+ }
536
+ const hasHydrationWarning = await fileHasSuppressHydrationWarning(layoutFilePath);
537
+ result.routerPatchability.appLayout.hasSuppressHydrationWarning =
538
+ hasHydrationWarning;
539
+ }
540
+ if (result.projectSanity.routerType === "pages" ||
541
+ result.projectSanity.routerType === "hybrid") {
542
+ let _appFilePath = "";
543
+ if (result.projectSanity.projectRoot === "src") {
544
+ _appFilePath = path_1.default.join(process.cwd(), "src", "pages", "_app.tsx");
545
+ }
546
+ else {
547
+ _appFilePath = path_1.default.join(process.cwd(), "pages", "_app.tsx");
548
+ }
549
+ result.routerPatchability.pagesApp.path = _appFilePath;
550
+ const _appExists = await (0, file_operations_1.fileExists)(_appFilePath);
551
+ result.routerPatchability.pagesApp.exists = _appExists;
552
+ const appWritableInfo = await fileIsWritable(_appFilePath);
553
+ result.routerPatchability.pagesApp.writableInfo = appWritableInfo;
554
+ const appWritableStatus = appWritableInfo.status;
555
+ if (appWritableStatus === "writable") {
556
+ result.routerPatchability.pagesApp.writable = true;
557
+ }
558
+ else if (appWritableStatus === "not-writable") {
559
+ result.routerPatchability.pagesApp.writable = false;
560
+ }
561
+ else {
562
+ result.routerPatchability.pagesApp.writable = null;
563
+ }
564
+ let _documentFilePath = "";
565
+ if (result.projectSanity.projectRoot === "src") {
566
+ _documentFilePath = path_1.default.join(process.cwd(), "src", "pages", "_document.tsx");
567
+ }
568
+ else {
569
+ _documentFilePath = path_1.default.join(process.cwd(), "pages", "_document.tsx");
570
+ }
571
+ result.routerPatchability.pagesDocument.path = _documentFilePath;
572
+ const _documentExists = await (0, file_operations_1.fileExists)(_documentFilePath);
573
+ result.routerPatchability.pagesDocument.exists = _documentExists;
574
+ const documentWritableInfo = await fileIsWritable(_documentFilePath);
575
+ result.routerPatchability.pagesDocument.writableInfo = documentWritableInfo;
576
+ const documentWritableStatus = documentWritableInfo.status;
577
+ if (documentWritableStatus === "writable") {
578
+ result.routerPatchability.pagesDocument.writable = true;
579
+ }
580
+ else if (documentWritableStatus === "not-writable") {
581
+ result.routerPatchability.pagesDocument.writable = false;
582
+ }
583
+ else {
584
+ result.routerPatchability.pagesDocument.writable = null;
585
+ }
586
+ const hasHydrationWarning = await fileHasSuppressHydrationWarning(_documentFilePath);
587
+ result.routerPatchability.pagesDocument.hasSuppressHydrationWarning =
588
+ hasHydrationWarning;
589
+ }
590
+ const shimDiagnostics = await getAppProvidersShimDiagnostics(cwd, result.projectSanity.routerType);
591
+ result.appProvidersShim = shimDiagnostics.shim;
592
+ result.warnings.push(...shimDiagnostics.warnings);
593
+ result.collisions = await getCollisionDiagnostics(cwd, mode ?? "root", result.projectSanity.routerType);
594
+ result.warnings.push(...result.collisions.paths
595
+ .filter((entry) => entry.exists)
596
+ .map((entry) => `Install collision detected: ${entry.path}`));
597
+ result.recordedInstallState = await getRecordedInstallState();
598
+ if (result.recordedInstallState.installedKits.length === 0) {
599
+ result.warnings.push("No recorded installed kits found in .nextworks/config.json.");
600
+ }
601
+ result.blocksFilePresence = getBlocksInstalledFileChecks(cwd, manifest, result.recordedInstallState);
602
+ for (const entry of result.blocksFilePresence) {
603
+ entry.exists = await (0, file_operations_1.fileExists)(entry.path);
604
+ if (!entry.exists) {
605
+ result.warnings.push(`Recorded Blocks install is missing expected file: ${entry.path}`);
606
+ }
607
+ }
608
+ const diagnostics = getRouterPatchabilityDiagnostics(result);
609
+ result.warnings.push(...diagnostics.warnings);
610
+ result.errors.push(...diagnostics.errors);
611
+ return result;
612
+ }
613
+ function formatDoctorResult(result) {
614
+ const lines = ["Doctor diagnostics"];
615
+ const iconFor = (status) => status === "ok" ? "✅" : status === "warning" ? "⚠️" : "❌";
616
+ lines.push("\nEnvironment");
617
+ lines.push(` ${iconFor(result.environmentChecks.nodeVersion.status)} ${result.environmentChecks.nodeVersion.message}`);
618
+ lines.push(` ✅ Package manager detected: ${result.environmentChecks.packageManager.pm} (${result.environmentChecks.packageManager.installCommand})`);
619
+ lines.push(` ${result.environmentChecks.yarnPnPDetection.isPnP ? "⚠️" : "✅"} Yarn Plug'n'Play ${result.environmentChecks.yarnPnPDetection.isPnP ? "detected" : "not detected"}`);
620
+ if (result.environmentChecks.yarnPnPDetection.isPnP)
621
+ lines.push(` ⚠️ ${result.environmentChecks.yarnPnPDetection.message}`);
622
+ lines.push("\nProject detection");
623
+ lines.push(` ${result.projectSanity.hasPackageJson ? "✅" : "❌"} package.json ${result.projectSanity.hasPackageJson ? "found" : "not found"}`);
624
+ lines.push(` ${result.projectSanity.hasNext ? "✅" : "❌"} Next.js dependency ${result.projectSanity.hasNext ? "found" : "not found"}`);
625
+ lines.push(` ${result.projectSanity.projectRoot ? "✅" : "❌"} Project root mode: ${result.projectSanity.projectRoot ?? "not detected"}`);
626
+ lines.push(` ${result.projectSanity.routerType ? "✅" : "❌"} Router type: ${result.projectSanity.routerType ?? "not detected"}`);
627
+ if (result.projectSanity.projectRootMode)
628
+ lines.push(` ✅ ${result.projectSanity.projectRootMode}`);
629
+ lines.push("\nRouter / patch targets");
630
+ if (result.projectSanity.routerType === "app" ||
631
+ result.projectSanity.routerType === "hybrid") {
632
+ lines.push(` ${result.routerPatchability.appLayout.exists ? "✅" : "⚠️"} app/layout.tsx: ${result.routerPatchability.appLayout.path}`);
633
+ lines.push(` ${result.routerPatchability.appLayout.exists ? (result.routerPatchability.appLayout.writableInfo.status === "not-writable" ? "❌" : "✅") : "⚠️"} Writable: ${String(result.routerPatchability.appLayout.writable)}`);
634
+ lines.push(` ${result.routerPatchability.appLayout.hasSuppressHydrationWarning.status === "found" ? "✅" : "⚠️"} suppressHydrationWarning: ${result.routerPatchability.appLayout.hasSuppressHydrationWarning.status}`);
635
+ }
636
+ if (result.projectSanity.routerType === "pages" ||
637
+ result.projectSanity.routerType === "hybrid") {
638
+ lines.push(` ${result.routerPatchability.pagesApp.exists ? "✅" : "⚠️"} pages/_app.tsx: ${result.routerPatchability.pagesApp.path}`);
639
+ lines.push(` ${result.routerPatchability.pagesApp.exists ? (result.routerPatchability.pagesApp.writableInfo.status === "not-writable" ? "❌" : "✅") : "⚠️"} Writable: ${String(result.routerPatchability.pagesApp.writable)}`);
640
+ lines.push(` ${result.routerPatchability.pagesDocument.exists ? "✅" : "⚠️"} pages/_document.tsx: ${result.routerPatchability.pagesDocument.path}`);
641
+ lines.push(` ${result.routerPatchability.pagesDocument.exists ? (result.routerPatchability.pagesDocument.writableInfo.status === "not-writable" || result.routerPatchability.pagesDocument.writableInfo.status === "not-found-parent-not-writable" ? "❌" : "✅") : "⚠️"} Writable: ${String(result.routerPatchability.pagesDocument.writable)}`);
642
+ lines.push(` ${result.routerPatchability.pagesDocument.hasSuppressHydrationWarning.status === "found" ? "✅" : "⚠️"} suppressHydrationWarning: ${result.routerPatchability.pagesDocument.hasSuppressHydrationWarning.status}`);
643
+ lines.push(` ${result.appProvidersShim.exists ? (result.appProvidersShim.targetMatchesRouter === false || result.appProvidersShim.targetExists === false ? "⚠️" : "✅") : "⚠️"} components/app-providers.tsx: ${result.appProvidersShim.path}`);
644
+ }
645
+ lines.push("\nKit prerequisites");
646
+ lines.push(` ${result.environmentChecks.tailwind.detected ? "✅" : "⚠️"} Tailwind CSS ${result.environmentChecks.tailwind.detected ? "detected" : "not detected"}`);
647
+ lines.push(` ${result.environmentChecks.typescript.detected ? "✅" : "❌"} TypeScript ${result.environmentChecks.typescript.detected ? "detected" : "not detected"}`);
648
+ lines.push("\nFilesystem / collisions");
649
+ lines.push(` ${result.projectRootWritability.writable === false ? "❌" : result.projectRootWritability.exists ? "✅" : "❌"} Project root writable: ${String(result.projectRootWritability.writable)}`);
650
+ const existingCollisions = result.collisions.paths.filter((collision) => collision.exists);
651
+ if (existingCollisions.length === 0) {
652
+ lines.push(" ✅ No install collisions detected");
653
+ }
654
+ else {
655
+ for (const entry of existingCollisions) {
656
+ lines.push(` ⚠️ Collision: ${entry.path}`);
657
+ }
658
+ }
659
+ lines.push("\nInstalled state");
660
+ if (result.recordedInstallState.installedKits.length === 0) {
661
+ lines.push(" ⚠️ No recorded installed kits found");
662
+ }
663
+ else {
664
+ for (const kit of result.recordedInstallState.installedKits) {
665
+ lines.push(` ✅ Recorded kit: ${kit.name}`);
666
+ }
667
+ }
668
+ const missingRecordedFiles = result.blocksFilePresence.filter((file) => !file.exists);
669
+ if (missingRecordedFiles.length > 0) {
670
+ for (const entry of missingRecordedFiles) {
671
+ lines.push(` ⚠️ Missing recorded file: ${entry.path}`);
672
+ }
673
+ }
674
+ lines.push("\nRecommendation");
675
+ if (result.errors.length === 0) {
676
+ lines.push(" ✅ Recommended next step: nextworks add blocks");
677
+ }
678
+ else {
679
+ const priorityError = result.errors[0];
680
+ lines.push(` ❌ Fix blocking issues before install: ${priorityError}`);
681
+ }
682
+ if (result.warnings.length) {
683
+ lines.push("\nWarnings");
684
+ for (const warning of result.warnings) {
685
+ lines.push(` ⚠️ ${warning}`);
686
+ }
687
+ }
688
+ if (result.errors.length) {
689
+ lines.push("\nErrors");
690
+ for (const error of result.errors) {
691
+ lines.push(` ❌ ${error}`);
692
+ }
693
+ }
694
+ return lines;
695
+ }
696
+ //# sourceMappingURL=doctor.js.map