@primeuicom/mcp 0.1.11 → 0.1.12
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.
- package/README.md +12 -2
- package/dist/service.js +270 -158
- package/dist/service.js.map +1 -1
- package/package.json +1 -1
package/dist/service.js
CHANGED
|
@@ -1,77 +1,178 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/service.ts
|
|
4
|
+
import path7 from "path";
|
|
4
5
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
6
|
|
|
7
|
+
// src/lib/project-link-config.ts
|
|
8
|
+
import { readFile, stat } from "fs/promises";
|
|
9
|
+
import path from "path";
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
var PRIMEUI_PROJECT_CONFIG_RELATIVE_PATH = ".primeui/project.json";
|
|
12
|
+
var primeUiProjectConfigSchema = z.object({
|
|
13
|
+
projectId: z.string().trim().min(1),
|
|
14
|
+
apiKey: z.string().trim().min(1),
|
|
15
|
+
targetProjectPath: z.string().trim().regex(/^\.\/.*$/)
|
|
16
|
+
}).passthrough();
|
|
17
|
+
async function fileExists(filePath) {
|
|
18
|
+
try {
|
|
19
|
+
const fileStats = await stat(filePath);
|
|
20
|
+
return fileStats.isFile();
|
|
21
|
+
} catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function ancestors(startPath) {
|
|
26
|
+
const resolvedStartPath = path.resolve(startPath);
|
|
27
|
+
const directories = [];
|
|
28
|
+
let currentPath = resolvedStartPath;
|
|
29
|
+
while (true) {
|
|
30
|
+
directories.push(currentPath);
|
|
31
|
+
const parentPath = path.dirname(currentPath);
|
|
32
|
+
if (parentPath === currentPath) {
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
currentPath = parentPath;
|
|
36
|
+
}
|
|
37
|
+
return directories;
|
|
38
|
+
}
|
|
39
|
+
async function findPrimeUiProjectConfigPath(startPath) {
|
|
40
|
+
for (const currentPath of ancestors(startPath)) {
|
|
41
|
+
const candidatePath = path.join(
|
|
42
|
+
currentPath,
|
|
43
|
+
PRIMEUI_PROJECT_CONFIG_RELATIVE_PATH
|
|
44
|
+
);
|
|
45
|
+
if (await fileExists(candidatePath)) {
|
|
46
|
+
return candidatePath;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return void 0;
|
|
50
|
+
}
|
|
51
|
+
async function readPrimeUiProjectConfig(projectConfigPath) {
|
|
52
|
+
let projectConfigRaw;
|
|
53
|
+
try {
|
|
54
|
+
projectConfigRaw = await readFile(projectConfigPath, "utf-8");
|
|
55
|
+
} catch (error) {
|
|
56
|
+
throw new Error(
|
|
57
|
+
`[primeui-mcp] failed to read ${PRIMEUI_PROJECT_CONFIG_RELATIVE_PATH}: ${error instanceof Error ? error.message : String(error)}`
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
let projectConfigJson;
|
|
61
|
+
try {
|
|
62
|
+
projectConfigJson = JSON.parse(projectConfigRaw);
|
|
63
|
+
} catch (error) {
|
|
64
|
+
throw new Error(
|
|
65
|
+
`[primeui-mcp] invalid JSON in ${PRIMEUI_PROJECT_CONFIG_RELATIVE_PATH}: ${error instanceof Error ? error.message : String(error)}`
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
const parsedConfig = primeUiProjectConfigSchema.safeParse(projectConfigJson);
|
|
69
|
+
if (!parsedConfig.success) {
|
|
70
|
+
const details = parsedConfig.error.issues.map((issue) => `${issue.path.join(".") || "<root>"}: ${issue.message}`).join("; ");
|
|
71
|
+
throw new Error(
|
|
72
|
+
`[primeui-mcp] invalid ${PRIMEUI_PROJECT_CONFIG_RELATIVE_PATH} format: ${details}`
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
return parsedConfig.data;
|
|
76
|
+
}
|
|
77
|
+
async function resolvePrimeUiProjectConfig(options) {
|
|
78
|
+
const envProjectRoot = options.projectRootFromEnv?.trim();
|
|
79
|
+
const projectConfigPath = envProjectRoot ? path.join(path.resolve(envProjectRoot), PRIMEUI_PROJECT_CONFIG_RELATIVE_PATH) : await findPrimeUiProjectConfigPath(options.cwd);
|
|
80
|
+
if (!projectConfigPath) {
|
|
81
|
+
throw new Error(
|
|
82
|
+
`[primeui-mcp] ${PRIMEUI_PROJECT_CONFIG_RELATIVE_PATH} not found from cwd (${options.cwd}).`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
const projectRoot = path.dirname(path.dirname(projectConfigPath));
|
|
86
|
+
const projectConfig = await readPrimeUiProjectConfig(projectConfigPath);
|
|
87
|
+
return {
|
|
88
|
+
projectRoot,
|
|
89
|
+
projectConfigPath,
|
|
90
|
+
projectConfig
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
async function resolvePrimeUiApiKey(options) {
|
|
94
|
+
const envApiKey = options.apiKeyFromEnv?.trim();
|
|
95
|
+
if (envApiKey) {
|
|
96
|
+
return envApiKey;
|
|
97
|
+
}
|
|
98
|
+
const projectConfigApiKey = options.projectConfig.apiKey.trim();
|
|
99
|
+
if (!projectConfigApiKey) {
|
|
100
|
+
throw new Error(
|
|
101
|
+
"[primeui-mcp] PRIMEUI_API_KEY is missing in env and .primeui/project.json"
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
return projectConfigApiKey;
|
|
105
|
+
}
|
|
106
|
+
|
|
6
107
|
// src/server.ts
|
|
7
108
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
8
109
|
|
|
9
110
|
// src/instructions.ts
|
|
10
|
-
import { z } from "zod/v3";
|
|
11
|
-
var pageSchema =
|
|
12
|
-
id:
|
|
111
|
+
import { z as z2 } from "zod/v3";
|
|
112
|
+
var pageSchema = z2.object({
|
|
113
|
+
id: z2.string().describe(
|
|
13
114
|
"Stable PrimeUI page identifier. Use this to match the same page across tool responses."
|
|
14
115
|
),
|
|
15
|
-
title:
|
|
116
|
+
title: z2.string().describe(
|
|
16
117
|
"Human-readable page title. Show this to the user when confirming which pages to import."
|
|
17
118
|
),
|
|
18
|
-
slug:
|
|
119
|
+
slug: z2.string().describe(
|
|
19
120
|
"PrimeUI route slug, for example '/', '/pricing', '/docs/getting-started'. Use to match user intent."
|
|
20
121
|
),
|
|
21
|
-
pageType:
|
|
122
|
+
pageType: z2.string().describe(
|
|
22
123
|
"PrimeUI page type classification (for example landing, docs, pricing, blogIndex, legal)."
|
|
23
124
|
),
|
|
24
|
-
isReadyToExport:
|
|
125
|
+
isReadyToExport: z2.boolean().describe(
|
|
25
126
|
"True when this page has an active export-ready variant. Only ready pages are expected in export output."
|
|
26
127
|
),
|
|
27
|
-
pagePath:
|
|
128
|
+
pagePath: z2.string().describe(
|
|
28
129
|
"Relative file path to the page source inside downloaded export root. Copy page code from this exact path."
|
|
29
130
|
),
|
|
30
|
-
componentsPath:
|
|
131
|
+
componentsPath: z2.string().describe(
|
|
31
132
|
"Relative directory path inside downloaded export root where page-level components live. Use as dependency copy start."
|
|
32
133
|
)
|
|
33
134
|
}).describe(
|
|
34
135
|
"PrimeUI page descriptor used by project and export tools. Paths are always relative to export project root."
|
|
35
136
|
);
|
|
36
|
-
var exportStatusSchema =
|
|
137
|
+
var exportStatusSchema = z2.enum(["in_progress", "completed", "failed"]).describe(
|
|
37
138
|
"Export lifecycle state. Use 'completed' before calling primeui_download_export."
|
|
38
139
|
);
|
|
39
|
-
var exportItemSchema =
|
|
40
|
-
id:
|
|
140
|
+
var exportItemSchema = z2.object({
|
|
141
|
+
id: z2.string().describe(
|
|
41
142
|
"Export identifier. Pass this value to primeui_download_export input.id."
|
|
42
143
|
),
|
|
43
144
|
status: exportStatusSchema,
|
|
44
|
-
createdAt:
|
|
145
|
+
createdAt: z2.string().describe("Export creation timestamp in ISO-8601 UTC format.")
|
|
45
146
|
}).describe("Single export record from PrimeUI export history.");
|
|
46
|
-
var fileTransferSchema =
|
|
47
|
-
sourcePath:
|
|
48
|
-
targetPath:
|
|
147
|
+
var fileTransferSchema = z2.object({
|
|
148
|
+
sourcePath: z2.string().describe("Relative source file path inside downloaded export root."),
|
|
149
|
+
targetPath: z2.string().describe("Relative target file path inside user project root.")
|
|
49
150
|
});
|
|
50
151
|
var conflictFileSchema = fileTransferSchema.extend({
|
|
51
|
-
diff:
|
|
152
|
+
diff: z2.string().describe(
|
|
52
153
|
"Unified diff between user file and export file. For binary files the diff contains a plain message."
|
|
53
154
|
),
|
|
54
|
-
isBinary:
|
|
155
|
+
isBinary: z2.boolean().describe("True if conflict comparison was treated as binary data.")
|
|
55
156
|
});
|
|
56
|
-
var dependencySectionSchema =
|
|
157
|
+
var dependencySectionSchema = z2.enum([
|
|
57
158
|
"dependencies",
|
|
58
159
|
"devDependencies",
|
|
59
160
|
"peerDependencies"
|
|
60
161
|
]);
|
|
61
|
-
var dependencyToAddSchema =
|
|
62
|
-
packageName:
|
|
63
|
-
version:
|
|
162
|
+
var dependencyToAddSchema = z2.object({
|
|
163
|
+
packageName: z2.string().describe("Dependency package name that was missing in user package.json."),
|
|
164
|
+
version: z2.string().describe("Version from exported project's package.json."),
|
|
64
165
|
section: dependencySectionSchema.describe(
|
|
65
166
|
"package.json section where dependency should be added."
|
|
66
167
|
)
|
|
67
168
|
});
|
|
68
|
-
var dependencyVersionConflictSchema =
|
|
69
|
-
packageName:
|
|
169
|
+
var dependencyVersionConflictSchema = z2.object({
|
|
170
|
+
packageName: z2.string().describe("Dependency package name with version mismatch."),
|
|
70
171
|
section: dependencySectionSchema.describe(
|
|
71
172
|
"Section where export expects this dependency."
|
|
72
173
|
),
|
|
73
|
-
exportVersion:
|
|
74
|
-
userVersion:
|
|
174
|
+
exportVersion: z2.string().describe("Version found in exported project's package.json."),
|
|
175
|
+
userVersion: z2.string().describe("Version currently present in user's package.json.")
|
|
75
176
|
});
|
|
76
177
|
var TRIGGER_PHRASES = [
|
|
77
178
|
"import page from PrimeUI",
|
|
@@ -145,16 +246,16 @@ AFTER CALLING:
|
|
|
145
246
|
${WORKFLOW_SUMMARY}`,
|
|
146
247
|
inputSchema: {},
|
|
147
248
|
outputSchema: {
|
|
148
|
-
projectId:
|
|
249
|
+
projectId: z2.string().describe(
|
|
149
250
|
"PrimeUI project identifier associated with the API key and current import session context."
|
|
150
251
|
),
|
|
151
|
-
projectName:
|
|
252
|
+
projectName: z2.string().describe(
|
|
152
253
|
"Human-readable PrimeUI project name for confirmations in chat."
|
|
153
254
|
),
|
|
154
|
-
metadata:
|
|
255
|
+
metadata: z2.record(z2.unknown()).describe(
|
|
155
256
|
"Additional project metadata from PrimeUI. May include project-description and other context fields."
|
|
156
257
|
),
|
|
157
|
-
pages:
|
|
258
|
+
pages: z2.array(pageSchema).describe(
|
|
158
259
|
"All pages visible for this project context. Filter by user request and isReadyToExport before creating export."
|
|
159
260
|
)
|
|
160
261
|
},
|
|
@@ -181,7 +282,7 @@ Do NOT use this tool as a substitute for primeui_create_export. Always create a
|
|
|
181
282
|
${WORKFLOW_SUMMARY}`,
|
|
182
283
|
inputSchema: {},
|
|
183
284
|
outputSchema: {
|
|
184
|
-
exports:
|
|
285
|
+
exports: z2.array(exportItemSchema).describe(
|
|
185
286
|
"Available exports sorted by API policy. Use item.id to download a specific prior export if user asks."
|
|
186
287
|
)
|
|
187
288
|
},
|
|
@@ -207,13 +308,13 @@ AFTER CALLING:
|
|
|
207
308
|
${WORKFLOW_SUMMARY}`,
|
|
208
309
|
inputSchema: {},
|
|
209
310
|
outputSchema: {
|
|
210
|
-
export:
|
|
211
|
-
id:
|
|
311
|
+
export: z2.object({
|
|
312
|
+
id: z2.string().describe(
|
|
212
313
|
"Freshly created export identifier. Use this as primeui_download_export input.id."
|
|
213
314
|
),
|
|
214
315
|
status: exportStatusSchema
|
|
215
316
|
}).describe("Created export summary."),
|
|
216
|
-
pages:
|
|
317
|
+
pages: z2.array(pageSchema).describe(
|
|
217
318
|
"Page snapshot associated with this export operation. Validate requested pages here before download/import."
|
|
218
319
|
)
|
|
219
320
|
},
|
|
@@ -246,21 +347,21 @@ AFTER DOWNLOAD:
|
|
|
246
347
|
|
|
247
348
|
${WORKFLOW_SUMMARY}`,
|
|
248
349
|
inputSchema: {
|
|
249
|
-
id:
|
|
350
|
+
id: z2.string().describe(
|
|
250
351
|
"Export identifier to download. Prefer export.id from primeui_create_export; use primeui_list_exports only on explicit user request."
|
|
251
352
|
)
|
|
252
353
|
},
|
|
253
354
|
outputSchema: {
|
|
254
|
-
exportId:
|
|
355
|
+
exportId: z2.string().describe(
|
|
255
356
|
"Downloaded export identifier. Should match the requested input.id for traceability."
|
|
256
357
|
),
|
|
257
|
-
projectPath:
|
|
358
|
+
projectPath: z2.string().describe(
|
|
258
359
|
"Absolute local path to extracted export root in .primeui/temp/exports/[exportId]. Read files from here only."
|
|
259
360
|
),
|
|
260
|
-
manifestPath:
|
|
361
|
+
manifestPath: z2.string().describe(
|
|
261
362
|
"Absolute path to sidecar export manifest file (.primeui/temp/exports/[exportId].manifest.json). primeui_copy_page depends on this file."
|
|
262
363
|
),
|
|
263
|
-
pages:
|
|
364
|
+
pages: z2.array(pageSchema).describe(
|
|
264
365
|
"Page descriptors for import decisions. Use pagePath/componentsPath from each item when copying code into user project."
|
|
265
366
|
)
|
|
266
367
|
},
|
|
@@ -295,44 +396,44 @@ BEHAVIOR:
|
|
|
295
396
|
|
|
296
397
|
${WORKFLOW_SUMMARY}`,
|
|
297
398
|
inputSchema: {
|
|
298
|
-
originPageSlug:
|
|
399
|
+
originPageSlug: z2.string().describe(
|
|
299
400
|
"Source page slug from PrimeUI project pages list, for example '/', '/pricing', '/docs'."
|
|
300
401
|
),
|
|
301
|
-
actualPageSlug:
|
|
402
|
+
actualPageSlug: z2.string().optional().describe(
|
|
302
403
|
"Optional destination slug in user's project. If omitted, originPageSlug is used."
|
|
303
404
|
)
|
|
304
405
|
},
|
|
305
406
|
outputSchema: {
|
|
306
|
-
exportId:
|
|
307
|
-
exportPath:
|
|
308
|
-
originPageSlug:
|
|
309
|
-
actualPageSlug:
|
|
310
|
-
sourcePagePath:
|
|
311
|
-
targetPagePath:
|
|
312
|
-
sourceComponentsPath:
|
|
313
|
-
targetComponentsPath:
|
|
407
|
+
exportId: z2.string().describe("Resolved local export identifier used for copy operation."),
|
|
408
|
+
exportPath: z2.string().describe("Absolute path to local extracted export project root."),
|
|
409
|
+
originPageSlug: z2.string().describe("Normalized source page slug requested for copy."),
|
|
410
|
+
actualPageSlug: z2.string().describe("Normalized destination slug used for target route paths."),
|
|
411
|
+
sourcePagePath: z2.string().describe("Source page path relative to export root."),
|
|
412
|
+
targetPagePath: z2.string().describe("Destination page path relative to user project root."),
|
|
413
|
+
sourceComponentsPath: z2.string().describe("Source components directory relative to export root."),
|
|
414
|
+
targetComponentsPath: z2.string().describe(
|
|
314
415
|
"Destination components directory relative to user project root."
|
|
315
416
|
),
|
|
316
|
-
newFiles:
|
|
317
|
-
identicalFiles:
|
|
417
|
+
newFiles: z2.array(fileTransferSchema).describe("New files copied into user project without conflicts."),
|
|
418
|
+
identicalFiles: z2.array(fileTransferSchema).describe(
|
|
318
419
|
"Existing files in user project that are byte-identical to export files."
|
|
319
420
|
),
|
|
320
|
-
conflictFiles:
|
|
421
|
+
conflictFiles: z2.array(conflictFileSchema).describe(
|
|
321
422
|
"Files that already exist and differ from export version. Never overwritten."
|
|
322
423
|
),
|
|
323
|
-
addedDependencies:
|
|
424
|
+
addedDependencies: z2.array(dependencyToAddSchema).describe(
|
|
324
425
|
"Dependencies that were missing and have been added to user's package.json."
|
|
325
426
|
),
|
|
326
|
-
dependenciesVersionConflicts:
|
|
427
|
+
dependenciesVersionConflicts: z2.array(dependencyVersionConflictSchema).describe(
|
|
327
428
|
"Dependencies with version mismatch between export and user project. Report only."
|
|
328
429
|
),
|
|
329
|
-
summary:
|
|
330
|
-
totalCandidateFiles:
|
|
331
|
-
copiedFiles:
|
|
332
|
-
identicalFiles:
|
|
333
|
-
conflictFiles:
|
|
334
|
-
addedDependencies:
|
|
335
|
-
dependenciesVersionConflicts:
|
|
430
|
+
summary: z2.object({
|
|
431
|
+
totalCandidateFiles: z2.number().describe("Total number of candidate files considered for page copy."),
|
|
432
|
+
copiedFiles: z2.number().describe("Number of files copied as new."),
|
|
433
|
+
identicalFiles: z2.number().describe("Number of files detected as identical."),
|
|
434
|
+
conflictFiles: z2.number().describe("Number of conflicting files not copied."),
|
|
435
|
+
addedDependencies: z2.number().describe("Count of dependencies added to package.json."),
|
|
436
|
+
dependenciesVersionConflicts: z2.number().describe("Count of dependency version mismatches reported.")
|
|
336
437
|
})
|
|
337
438
|
},
|
|
338
439
|
annotations: {
|
|
@@ -355,7 +456,7 @@ Safe to call multiple times. Only affects .primeui/temp/ directory - never touch
|
|
|
355
456
|
${WORKFLOW_SUMMARY}`,
|
|
356
457
|
inputSchema: {},
|
|
357
458
|
outputSchema: {
|
|
358
|
-
success:
|
|
459
|
+
success: z2.boolean().describe(
|
|
359
460
|
"True when temp cleanup completed and baseline temp structure was recreated."
|
|
360
461
|
)
|
|
361
462
|
},
|
|
@@ -470,12 +571,12 @@ function createPrimeUiMcpServer(source) {
|
|
|
470
571
|
}
|
|
471
572
|
|
|
472
573
|
// src/services/project-sync-service.ts
|
|
473
|
-
import
|
|
474
|
-
import { readFile as
|
|
574
|
+
import path5 from "path";
|
|
575
|
+
import { readFile as readFile4 } from "fs/promises";
|
|
475
576
|
|
|
476
577
|
// src/lib/fs.ts
|
|
477
578
|
import { mkdir, rm, writeFile } from "fs/promises";
|
|
478
|
-
import
|
|
579
|
+
import path2 from "path";
|
|
479
580
|
import extractZipArchive from "extract-zip";
|
|
480
581
|
async function ensureDir(dirPath) {
|
|
481
582
|
await mkdir(dirPath, { recursive: true });
|
|
@@ -485,7 +586,7 @@ async function resetDir(dirPath) {
|
|
|
485
586
|
await mkdir(dirPath, { recursive: true });
|
|
486
587
|
}
|
|
487
588
|
async function writeUtf8(filePath, content) {
|
|
488
|
-
await ensureDir(
|
|
589
|
+
await ensureDir(path2.dirname(filePath));
|
|
489
590
|
await writeFile(filePath, content, "utf-8");
|
|
490
591
|
}
|
|
491
592
|
async function extractZip(zipPath, targetDir) {
|
|
@@ -499,13 +600,13 @@ async function extractZip(zipPath, targetDir) {
|
|
|
499
600
|
}
|
|
500
601
|
|
|
501
602
|
// src/services/page-copy-service.ts
|
|
502
|
-
import { readFile as
|
|
503
|
-
import
|
|
603
|
+
import { readFile as readFile3, readdir, stat as stat3, writeFile as writeFile2 } from "fs/promises";
|
|
604
|
+
import path4 from "path";
|
|
504
605
|
|
|
505
606
|
// src/lib/import-graph.ts
|
|
506
|
-
import { readFile, stat } from "fs/promises";
|
|
607
|
+
import { readFile as readFile2, stat as stat2 } from "fs/promises";
|
|
507
608
|
import { builtinModules } from "module";
|
|
508
|
-
import
|
|
609
|
+
import path3 from "path";
|
|
509
610
|
var INTERNAL_EXTENSIONS = [
|
|
510
611
|
".ts",
|
|
511
612
|
".tsx",
|
|
@@ -574,14 +675,14 @@ function getExternalPackageName(specifier) {
|
|
|
574
675
|
}
|
|
575
676
|
async function pathExists(filePath) {
|
|
576
677
|
try {
|
|
577
|
-
await
|
|
678
|
+
await stat2(filePath);
|
|
578
679
|
return true;
|
|
579
680
|
} catch {
|
|
580
681
|
return false;
|
|
581
682
|
}
|
|
582
683
|
}
|
|
583
684
|
async function resolveFileCandidate(candidateBase) {
|
|
584
|
-
const ext =
|
|
685
|
+
const ext = path3.extname(candidateBase);
|
|
585
686
|
if (ext) {
|
|
586
687
|
if (await pathExists(candidateBase)) {
|
|
587
688
|
return candidateBase;
|
|
@@ -595,13 +696,13 @@ async function resolveFileCandidate(candidateBase) {
|
|
|
595
696
|
}
|
|
596
697
|
}
|
|
597
698
|
if (await pathExists(candidateBase)) {
|
|
598
|
-
const stats = await
|
|
699
|
+
const stats = await stat2(candidateBase);
|
|
599
700
|
if (stats.isFile()) {
|
|
600
701
|
return candidateBase;
|
|
601
702
|
}
|
|
602
703
|
if (stats.isDirectory()) {
|
|
603
704
|
for (const extension of INTERNAL_EXTENSIONS) {
|
|
604
|
-
const indexCandidate =
|
|
705
|
+
const indexCandidate = path3.join(candidateBase, `index${extension}`);
|
|
605
706
|
if (await pathExists(indexCandidate)) {
|
|
606
707
|
return indexCandidate;
|
|
607
708
|
}
|
|
@@ -623,13 +724,13 @@ async function resolveImportToFile(projectRoot, importerFilePath, specifier) {
|
|
|
623
724
|
}
|
|
624
725
|
let candidateBase = null;
|
|
625
726
|
if (specifier.startsWith("@/")) {
|
|
626
|
-
candidateBase =
|
|
727
|
+
candidateBase = path3.join(projectRoot, "src", specifier.slice(2));
|
|
627
728
|
} else if (specifier.startsWith("@root/")) {
|
|
628
|
-
candidateBase =
|
|
729
|
+
candidateBase = path3.join(projectRoot, specifier.slice(6));
|
|
629
730
|
} else if (specifier.startsWith(".")) {
|
|
630
|
-
candidateBase =
|
|
731
|
+
candidateBase = path3.resolve(path3.dirname(importerFilePath), specifier);
|
|
631
732
|
} else if (specifier.startsWith("/")) {
|
|
632
|
-
candidateBase =
|
|
733
|
+
candidateBase = path3.join(projectRoot, specifier.slice(1));
|
|
633
734
|
} else {
|
|
634
735
|
return { kind: "unknown" };
|
|
635
736
|
}
|
|
@@ -643,11 +744,11 @@ async function resolveImportToFile(projectRoot, importerFilePath, specifier) {
|
|
|
643
744
|
};
|
|
644
745
|
}
|
|
645
746
|
function shouldParseFile(filePath) {
|
|
646
|
-
return PARSEABLE_EXTENSIONS.has(
|
|
747
|
+
return PARSEABLE_EXTENSIONS.has(path3.extname(filePath).toLowerCase());
|
|
647
748
|
}
|
|
648
749
|
async function buildImportGraph(input) {
|
|
649
|
-
const projectRoot =
|
|
650
|
-
const queue = input.entryFiles.map((filePath) =>
|
|
750
|
+
const projectRoot = path3.resolve(input.projectRoot);
|
|
751
|
+
const queue = input.entryFiles.map((filePath) => path3.resolve(filePath));
|
|
651
752
|
const visited = /* @__PURE__ */ new Set();
|
|
652
753
|
const internalFiles = /* @__PURE__ */ new Set();
|
|
653
754
|
const externalPackages = /* @__PURE__ */ new Set();
|
|
@@ -663,7 +764,7 @@ async function buildImportGraph(input) {
|
|
|
663
764
|
}
|
|
664
765
|
let content = "";
|
|
665
766
|
try {
|
|
666
|
-
content = await
|
|
767
|
+
content = await readFile2(currentFilePath, "utf-8");
|
|
667
768
|
} catch {
|
|
668
769
|
continue;
|
|
669
770
|
}
|
|
@@ -900,10 +1001,10 @@ function normalizeSlug2(slug) {
|
|
|
900
1001
|
return withLeadingSlash.replace(/\/+$/, "") || "/";
|
|
901
1002
|
}
|
|
902
1003
|
function toPosixPath(value) {
|
|
903
|
-
return value.split(
|
|
1004
|
+
return value.split(path4.sep).join("/");
|
|
904
1005
|
}
|
|
905
1006
|
function toProjectRelative(rootPath, absolutePath) {
|
|
906
|
-
return toPosixPath(
|
|
1007
|
+
return toPosixPath(path4.relative(rootPath, absolutePath));
|
|
907
1008
|
}
|
|
908
1009
|
function escapeRegExp(value) {
|
|
909
1010
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -960,7 +1061,7 @@ function buildPlannedSourceBuffer(sourceBuffer, sourceFilePath, importRewritePla
|
|
|
960
1061
|
if (!importRewritePlan) {
|
|
961
1062
|
return sourceBuffer;
|
|
962
1063
|
}
|
|
963
|
-
const extension =
|
|
1064
|
+
const extension = path4.extname(sourceFilePath).toLowerCase();
|
|
964
1065
|
if (!REWRITABLE_IMPORT_EXTENSIONS.has(extension)) {
|
|
965
1066
|
return sourceBuffer;
|
|
966
1067
|
}
|
|
@@ -968,19 +1069,22 @@ function buildPlannedSourceBuffer(sourceBuffer, sourceFilePath, importRewritePla
|
|
|
968
1069
|
return sourceBuffer;
|
|
969
1070
|
}
|
|
970
1071
|
const sourceText = sourceBuffer.toString("utf-8");
|
|
971
|
-
const rewritten = rewriteImportsForRemappedSlug(
|
|
1072
|
+
const rewritten = rewriteImportsForRemappedSlug(
|
|
1073
|
+
sourceText,
|
|
1074
|
+
importRewritePlan
|
|
1075
|
+
);
|
|
972
1076
|
if (rewritten === sourceText) {
|
|
973
1077
|
return sourceBuffer;
|
|
974
1078
|
}
|
|
975
1079
|
return Buffer.from(rewritten, "utf-8");
|
|
976
1080
|
}
|
|
977
1081
|
async function readJsonFile(filePath) {
|
|
978
|
-
const content = await
|
|
1082
|
+
const content = await readFile3(filePath, "utf-8");
|
|
979
1083
|
return JSON.parse(content);
|
|
980
1084
|
}
|
|
981
|
-
async function
|
|
1085
|
+
async function fileExists2(filePath) {
|
|
982
1086
|
try {
|
|
983
|
-
await
|
|
1087
|
+
await stat3(filePath);
|
|
984
1088
|
return true;
|
|
985
1089
|
} catch {
|
|
986
1090
|
return false;
|
|
@@ -1022,7 +1126,7 @@ async function listFilesRecursively(dirPath) {
|
|
|
1022
1126
|
}
|
|
1023
1127
|
const entries = await readdir(current, { withFileTypes: true });
|
|
1024
1128
|
for (const entry of entries) {
|
|
1025
|
-
const absolutePath =
|
|
1129
|
+
const absolutePath = path4.join(current, entry.name);
|
|
1026
1130
|
if (entry.isDirectory()) {
|
|
1027
1131
|
stack.push(absolutePath);
|
|
1028
1132
|
continue;
|
|
@@ -1050,12 +1154,12 @@ async function resolveSingleExportDirectory(exportsRoot) {
|
|
|
1050
1154
|
const exportId = exportDirectories[0] ?? "";
|
|
1051
1155
|
return {
|
|
1052
1156
|
exportId,
|
|
1053
|
-
exportPath:
|
|
1157
|
+
exportPath: path4.join(exportsRoot, exportId)
|
|
1054
1158
|
};
|
|
1055
1159
|
}
|
|
1056
1160
|
function ensureSafeTargetPath(projectRoot, targetPath) {
|
|
1057
|
-
const relative =
|
|
1058
|
-
if (relative.startsWith("..") ||
|
|
1161
|
+
const relative = path4.relative(projectRoot, targetPath);
|
|
1162
|
+
if (relative.startsWith("..") || path4.isAbsolute(relative)) {
|
|
1059
1163
|
throw new Error(
|
|
1060
1164
|
`Refusing to write outside project root. Computed target: ${targetPath}`
|
|
1061
1165
|
);
|
|
@@ -1113,19 +1217,19 @@ function resolveTargetFilePath(input) {
|
|
|
1113
1217
|
if (sourceFilePath === sourcePagePath) {
|
|
1114
1218
|
return targetPagePath;
|
|
1115
1219
|
}
|
|
1116
|
-
const componentsPrefix = `${sourceComponentsPath}${
|
|
1220
|
+
const componentsPrefix = `${sourceComponentsPath}${path4.sep}`;
|
|
1117
1221
|
if (sourceFilePath === sourceComponentsPath || sourceFilePath.startsWith(componentsPrefix)) {
|
|
1118
|
-
const relativeToComponents =
|
|
1222
|
+
const relativeToComponents = path4.relative(
|
|
1119
1223
|
sourceComponentsPath,
|
|
1120
1224
|
sourceFilePath
|
|
1121
1225
|
);
|
|
1122
|
-
return
|
|
1226
|
+
return path4.join(targetComponentsPath, relativeToComponents);
|
|
1123
1227
|
}
|
|
1124
|
-
const relativeToExport =
|
|
1125
|
-
if (relativeToExport.startsWith("..") ||
|
|
1228
|
+
const relativeToExport = path4.relative(exportRoot, sourceFilePath);
|
|
1229
|
+
if (relativeToExport.startsWith("..") || path4.isAbsolute(relativeToExport)) {
|
|
1126
1230
|
throw new Error(`Source file is outside export root: ${sourceFilePath}`);
|
|
1127
1231
|
}
|
|
1128
|
-
return
|
|
1232
|
+
return path4.join(projectRoot, relativeToExport);
|
|
1129
1233
|
}
|
|
1130
1234
|
async function copyPageFromExport(input) {
|
|
1131
1235
|
const normalizedOriginSlug = normalizeSlug2(input.originPageSlug);
|
|
@@ -1136,11 +1240,11 @@ async function copyPageFromExport(input) {
|
|
|
1136
1240
|
const { exportId, exportPath } = await resolveSingleExportDirectory(
|
|
1137
1241
|
input.exportsRoot
|
|
1138
1242
|
);
|
|
1139
|
-
const manifestPath =
|
|
1243
|
+
const manifestPath = path4.join(
|
|
1140
1244
|
input.exportsRoot,
|
|
1141
1245
|
`${exportId}.manifest.json`
|
|
1142
1246
|
);
|
|
1143
|
-
if (!await
|
|
1247
|
+
if (!await fileExists2(manifestPath)) {
|
|
1144
1248
|
throw new Error(
|
|
1145
1249
|
`Export manifest is missing at ${manifestPath}. Run primeui_download_export to regenerate it.`
|
|
1146
1250
|
);
|
|
@@ -1159,13 +1263,13 @@ async function copyPageFromExport(input) {
|
|
|
1159
1263
|
`Page not found in manifest for slug: ${normalizedOriginSlug}`
|
|
1160
1264
|
);
|
|
1161
1265
|
}
|
|
1162
|
-
const sourcePagePath =
|
|
1163
|
-
const sourceComponentsPath =
|
|
1164
|
-
const sourcePageStats = await
|
|
1266
|
+
const sourcePagePath = path4.join(exportPath, page.pagePath);
|
|
1267
|
+
const sourceComponentsPath = path4.join(exportPath, page.componentsPath);
|
|
1268
|
+
const sourcePageStats = await stat3(sourcePagePath).catch(() => null);
|
|
1165
1269
|
if (!sourcePageStats?.isFile()) {
|
|
1166
1270
|
throw new Error(`Source page file not found: ${sourcePagePath}`);
|
|
1167
1271
|
}
|
|
1168
|
-
const sourceComponentsStats = await
|
|
1272
|
+
const sourceComponentsStats = await stat3(sourceComponentsPath).catch(
|
|
1169
1273
|
() => null
|
|
1170
1274
|
);
|
|
1171
1275
|
if (!sourceComponentsStats?.isDirectory()) {
|
|
@@ -1180,8 +1284,8 @@ async function copyPageFromExport(input) {
|
|
|
1180
1284
|
pageType: page.pageType,
|
|
1181
1285
|
slug: normalizedActualSlug
|
|
1182
1286
|
});
|
|
1183
|
-
const targetPagePath =
|
|
1184
|
-
const targetComponentsPath =
|
|
1287
|
+
const targetPagePath = path4.join(input.projectRoot, targetPaths.pagePath);
|
|
1288
|
+
const targetComponentsPath = path4.join(
|
|
1185
1289
|
input.projectRoot,
|
|
1186
1290
|
targetPaths.componentsPath
|
|
1187
1291
|
);
|
|
@@ -1211,7 +1315,7 @@ async function copyPageFromExport(input) {
|
|
|
1211
1315
|
projectRoot: input.projectRoot
|
|
1212
1316
|
});
|
|
1213
1317
|
ensureSafeTargetPath(input.projectRoot, targetFilePath);
|
|
1214
|
-
const sourceBuffer = await
|
|
1318
|
+
const sourceBuffer = await readFile3(sourceFilePath);
|
|
1215
1319
|
const plannedSourceBuffer = buildPlannedSourceBuffer(
|
|
1216
1320
|
sourceBuffer,
|
|
1217
1321
|
sourceFilePath,
|
|
@@ -1219,14 +1323,14 @@ async function copyPageFromExport(input) {
|
|
|
1219
1323
|
);
|
|
1220
1324
|
let targetBuffer = null;
|
|
1221
1325
|
try {
|
|
1222
|
-
targetBuffer = await
|
|
1326
|
+
targetBuffer = await readFile3(targetFilePath);
|
|
1223
1327
|
} catch {
|
|
1224
1328
|
targetBuffer = null;
|
|
1225
1329
|
}
|
|
1226
1330
|
const sourceRelative = toProjectRelative(exportPath, sourceFilePath);
|
|
1227
1331
|
const targetRelative = toProjectRelative(input.projectRoot, targetFilePath);
|
|
1228
1332
|
if (!targetBuffer) {
|
|
1229
|
-
await ensureDir(
|
|
1333
|
+
await ensureDir(path4.dirname(targetFilePath));
|
|
1230
1334
|
await writeFile2(targetFilePath, plannedSourceBuffer);
|
|
1231
1335
|
newFiles.push({
|
|
1232
1336
|
sourcePath: sourceRelative,
|
|
@@ -1255,12 +1359,12 @@ async function copyPageFromExport(input) {
|
|
|
1255
1359
|
isBinary
|
|
1256
1360
|
});
|
|
1257
1361
|
}
|
|
1258
|
-
const exportPackageJsonPath =
|
|
1259
|
-
const userPackageJsonPath =
|
|
1260
|
-
if (!await
|
|
1362
|
+
const exportPackageJsonPath = path4.join(exportPath, "package.json");
|
|
1363
|
+
const userPackageJsonPath = path4.join(input.projectRoot, "package.json");
|
|
1364
|
+
if (!await fileExists2(exportPackageJsonPath)) {
|
|
1261
1365
|
throw new Error(`Export package.json not found: ${exportPackageJsonPath}`);
|
|
1262
1366
|
}
|
|
1263
|
-
if (!await
|
|
1367
|
+
if (!await fileExists2(userPackageJsonPath)) {
|
|
1264
1368
|
throw new Error(`User package.json not found: ${userPackageJsonPath}`);
|
|
1265
1369
|
}
|
|
1266
1370
|
const exportPackageJson = await readJsonFile(
|
|
@@ -1347,7 +1451,7 @@ function isProjectPage(value) {
|
|
|
1347
1451
|
return typeof maybe.id === "string" && typeof maybe.title === "string" && typeof maybe.slug === "string" && typeof maybe.pageType === "string" && typeof maybe.isReadyToExport === "boolean" && typeof maybe.pagePath === "string" && typeof maybe.componentsPath === "string";
|
|
1348
1452
|
}
|
|
1349
1453
|
function buildPagesSnapshotPath(exportsRoot, exportId) {
|
|
1350
|
-
return
|
|
1454
|
+
return path5.join(exportsRoot, `${exportId}.pages.snapshot.json`);
|
|
1351
1455
|
}
|
|
1352
1456
|
function parsePagesSnapshot(value) {
|
|
1353
1457
|
if (!value || typeof value !== "object") {
|
|
@@ -1376,9 +1480,9 @@ var ProjectSyncService = class {
|
|
|
1376
1480
|
constructor(options) {
|
|
1377
1481
|
this.projectRoot = options.projectRoot;
|
|
1378
1482
|
this.provider = options.provider;
|
|
1379
|
-
this.primeUiRoot =
|
|
1380
|
-
this.tempRoot =
|
|
1381
|
-
this.exportsRoot =
|
|
1483
|
+
this.primeUiRoot = path5.join(this.projectRoot, ".primeui");
|
|
1484
|
+
this.tempRoot = path5.join(this.primeUiRoot, "temp");
|
|
1485
|
+
this.exportsRoot = path5.join(this.tempRoot, "exports");
|
|
1382
1486
|
}
|
|
1383
1487
|
async getProjectInfo() {
|
|
1384
1488
|
await this.ensureTempLayout();
|
|
@@ -1415,8 +1519,8 @@ var ProjectSyncService = class {
|
|
|
1415
1519
|
if (!selected) {
|
|
1416
1520
|
throw new Error(`Export not found: ${id}`);
|
|
1417
1521
|
}
|
|
1418
|
-
const targetZipPath =
|
|
1419
|
-
const targetProjectPath =
|
|
1522
|
+
const targetZipPath = path5.join(this.exportsRoot, `${id}.zip`);
|
|
1523
|
+
const targetProjectPath = path5.join(this.exportsRoot, id);
|
|
1420
1524
|
await ensureDir(this.exportsRoot);
|
|
1421
1525
|
await this.provider.downloadExportArchive(id, targetZipPath);
|
|
1422
1526
|
await resetDir(targetProjectPath);
|
|
@@ -1425,7 +1529,7 @@ var ProjectSyncService = class {
|
|
|
1425
1529
|
let pagesSnapshot;
|
|
1426
1530
|
try {
|
|
1427
1531
|
const snapshotRaw = JSON.parse(
|
|
1428
|
-
await
|
|
1532
|
+
await readFile4(pagesSnapshotPath, "utf-8")
|
|
1429
1533
|
);
|
|
1430
1534
|
pagesSnapshot = parsePagesSnapshot(snapshotRaw);
|
|
1431
1535
|
} catch (error) {
|
|
@@ -1440,7 +1544,7 @@ var ProjectSyncService = class {
|
|
|
1440
1544
|
);
|
|
1441
1545
|
}
|
|
1442
1546
|
const pages = pagesSnapshot.pages;
|
|
1443
|
-
const manifestPath =
|
|
1547
|
+
const manifestPath = path5.join(this.exportsRoot, `${id}.manifest.json`);
|
|
1444
1548
|
const manifest = {
|
|
1445
1549
|
schemaVersion: 1,
|
|
1446
1550
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -1468,61 +1572,61 @@ var ProjectSyncService = class {
|
|
|
1468
1572
|
}
|
|
1469
1573
|
async clearTemp() {
|
|
1470
1574
|
await resetDir(this.tempRoot);
|
|
1471
|
-
await writeUtf8(
|
|
1575
|
+
await writeUtf8(path5.join(this.tempRoot, ".gitkeep"), "");
|
|
1472
1576
|
await ensureDir(this.exportsRoot);
|
|
1473
1577
|
}
|
|
1474
1578
|
async ensureTempLayout() {
|
|
1475
1579
|
await ensureDir(this.primeUiRoot);
|
|
1476
1580
|
await ensureDir(this.tempRoot);
|
|
1477
1581
|
await ensureDir(this.exportsRoot);
|
|
1478
|
-
await writeUtf8(
|
|
1582
|
+
await writeUtf8(path5.join(this.tempRoot, ".gitkeep"), "");
|
|
1479
1583
|
}
|
|
1480
1584
|
};
|
|
1481
1585
|
|
|
1482
1586
|
// src/sources/api-provider.ts
|
|
1483
1587
|
import { createWriteStream } from "fs";
|
|
1484
1588
|
import { unlink } from "fs/promises";
|
|
1485
|
-
import
|
|
1589
|
+
import path6 from "path";
|
|
1486
1590
|
import { Readable, Transform } from "stream";
|
|
1487
1591
|
import { pipeline } from "stream/promises";
|
|
1488
|
-
import { z as
|
|
1592
|
+
import { z as z3 } from "zod";
|
|
1489
1593
|
var DEFAULT_API_BASE_URL = "https://app.primeui.com/";
|
|
1490
1594
|
var ZIP_CONTENT_TYPES = [
|
|
1491
1595
|
"application/zip",
|
|
1492
1596
|
"application/octet-stream",
|
|
1493
1597
|
"application/x-zip-compressed"
|
|
1494
1598
|
];
|
|
1495
|
-
var exportStatusSchema2 =
|
|
1496
|
-
var projectPageSchema =
|
|
1497
|
-
id:
|
|
1498
|
-
title:
|
|
1499
|
-
slug:
|
|
1500
|
-
pageType:
|
|
1501
|
-
isReadyToExport:
|
|
1502
|
-
pagePath:
|
|
1503
|
-
componentsPath:
|
|
1599
|
+
var exportStatusSchema2 = z3.enum(["in_progress", "completed", "failed"]);
|
|
1600
|
+
var projectPageSchema = z3.object({
|
|
1601
|
+
id: z3.string(),
|
|
1602
|
+
title: z3.string(),
|
|
1603
|
+
slug: z3.string(),
|
|
1604
|
+
pageType: z3.string(),
|
|
1605
|
+
isReadyToExport: z3.boolean(),
|
|
1606
|
+
pagePath: z3.string(),
|
|
1607
|
+
componentsPath: z3.string()
|
|
1504
1608
|
});
|
|
1505
|
-
var projectInfoSchema =
|
|
1506
|
-
projectId:
|
|
1507
|
-
projectName:
|
|
1508
|
-
metadata:
|
|
1509
|
-
pages:
|
|
1609
|
+
var projectInfoSchema = z3.object({
|
|
1610
|
+
projectId: z3.string(),
|
|
1611
|
+
projectName: z3.string(),
|
|
1612
|
+
metadata: z3.record(z3.unknown()),
|
|
1613
|
+
pages: z3.array(projectPageSchema)
|
|
1510
1614
|
});
|
|
1511
|
-
var exportsResponseSchema =
|
|
1512
|
-
exports:
|
|
1513
|
-
|
|
1514
|
-
id:
|
|
1615
|
+
var exportsResponseSchema = z3.object({
|
|
1616
|
+
exports: z3.array(
|
|
1617
|
+
z3.object({
|
|
1618
|
+
id: z3.string(),
|
|
1515
1619
|
status: exportStatusSchema2,
|
|
1516
|
-
createdAt:
|
|
1620
|
+
createdAt: z3.string().datetime({ offset: true })
|
|
1517
1621
|
})
|
|
1518
1622
|
)
|
|
1519
1623
|
});
|
|
1520
|
-
var createExportResponseSchema =
|
|
1521
|
-
export:
|
|
1522
|
-
id:
|
|
1624
|
+
var createExportResponseSchema = z3.object({
|
|
1625
|
+
export: z3.object({
|
|
1626
|
+
id: z3.string(),
|
|
1523
1627
|
status: exportStatusSchema2
|
|
1524
1628
|
}),
|
|
1525
|
-
pages:
|
|
1629
|
+
pages: z3.array(projectPageSchema)
|
|
1526
1630
|
});
|
|
1527
1631
|
var PrimeUiApiContractError = class extends Error {
|
|
1528
1632
|
constructor(endpoint, details) {
|
|
@@ -1651,7 +1755,7 @@ var ApiProjectDataProvider = class {
|
|
|
1651
1755
|
if (!response.body) {
|
|
1652
1756
|
throw new PrimeUiApiContractError(endpoint, "response body is empty");
|
|
1653
1757
|
}
|
|
1654
|
-
await ensureDir(
|
|
1758
|
+
await ensureDir(path6.dirname(destinationPath));
|
|
1655
1759
|
const zipStream = Readable.fromWeb(
|
|
1656
1760
|
response.body
|
|
1657
1761
|
);
|
|
@@ -1739,22 +1843,30 @@ var ApiProjectDataProvider = class {
|
|
|
1739
1843
|
|
|
1740
1844
|
// src/service.ts
|
|
1741
1845
|
async function main() {
|
|
1742
|
-
const
|
|
1743
|
-
|
|
1846
|
+
const resolvedProjectConfig = await resolvePrimeUiProjectConfig({
|
|
1847
|
+
cwd: process.cwd(),
|
|
1848
|
+
projectRootFromEnv: process.env.PRIMEUI_PROJECT_ROOT
|
|
1849
|
+
});
|
|
1850
|
+
const projectRoot = resolvedProjectConfig.projectRoot;
|
|
1851
|
+
const targetProjectRoot = path7.resolve(
|
|
1852
|
+
projectRoot,
|
|
1853
|
+
resolvedProjectConfig.projectConfig.targetProjectPath
|
|
1854
|
+
);
|
|
1855
|
+
const apiKey = await resolvePrimeUiApiKey({
|
|
1856
|
+
projectConfig: resolvedProjectConfig.projectConfig,
|
|
1857
|
+
apiKeyFromEnv: process.env.PRIMEUI_API_KEY
|
|
1858
|
+
});
|
|
1744
1859
|
const provider = new ApiProjectDataProvider({
|
|
1745
1860
|
apiKey,
|
|
1746
1861
|
baseUrl: process.env.PRIMEUI_API_BASE_URL
|
|
1747
1862
|
});
|
|
1748
|
-
if (!apiKey) {
|
|
1749
|
-
console.error(
|
|
1750
|
-
"[primeui-mcp] warning: PRIMEUI_API_KEY is not set; API-backed tools will fail until it is configured."
|
|
1751
|
-
);
|
|
1752
|
-
}
|
|
1753
1863
|
const syncService = new ProjectSyncService({ projectRoot, provider });
|
|
1754
1864
|
const server = createPrimeUiMcpServer(syncService);
|
|
1755
1865
|
const transport = new StdioServerTransport();
|
|
1756
1866
|
await server.connect(transport);
|
|
1757
|
-
console.error(
|
|
1867
|
+
console.error(
|
|
1868
|
+
`[primeui-mcp] running for root: ${projectRoot}; target project: ${targetProjectRoot}`
|
|
1869
|
+
);
|
|
1758
1870
|
}
|
|
1759
1871
|
main().catch((error) => {
|
|
1760
1872
|
console.error("[primeui-mcp] failed to start", error);
|