@primeuicom/mcp 1.2.2 → 1.2.4
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/dist/service.js +614 -19
- package/dist/service.js.map +1 -1
- package/package.json +1 -1
package/dist/service.js
CHANGED
|
@@ -229,6 +229,7 @@ function buildProjectRootHint() {
|
|
|
229
229
|
var primeUiProjectConfigSchema = z2.object({
|
|
230
230
|
projectId: z2.string().trim().min(1),
|
|
231
231
|
apiKey: z2.string().trim().min(1),
|
|
232
|
+
apiBaseUrl: z2.string().trim().url().optional(),
|
|
232
233
|
targetProjectPath: z2.string().trim().regex(/^\.\/.*$/).optional()
|
|
233
234
|
}).passthrough();
|
|
234
235
|
var primeUiProjectConfigWithTargetPathSchema = primeUiProjectConfigSchema.superRefine((value, ctx) => {
|
|
@@ -519,6 +520,23 @@ async function resolvePrimeUiApiKey(options) {
|
|
|
519
520
|
hint: "Set PRIMEUI_API_KEY or ensure apiKey is present in .primeui/project.json."
|
|
520
521
|
});
|
|
521
522
|
}
|
|
523
|
+
function resolvePrimeUiApiBaseUrlDetails(options) {
|
|
524
|
+
const envBaseUrl = options.baseUrlFromEnv?.trim();
|
|
525
|
+
const configBaseUrl = options.projectConfig?.apiBaseUrl?.trim();
|
|
526
|
+
const envProvided = Boolean(envBaseUrl);
|
|
527
|
+
const configProvided = Boolean(configBaseUrl);
|
|
528
|
+
const resolvedBaseUrl = envBaseUrl || configBaseUrl;
|
|
529
|
+
return {
|
|
530
|
+
baseUrl: resolvedBaseUrl,
|
|
531
|
+
source: envProvided ? "env" : configProvided ? "config" : "default",
|
|
532
|
+
envProvided,
|
|
533
|
+
configProvided,
|
|
534
|
+
valuesMatch: envProvided && configProvided ? envBaseUrl === configBaseUrl : void 0
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
function resolvePrimeUiApiBaseUrl(options) {
|
|
538
|
+
return resolvePrimeUiApiBaseUrlDetails(options).baseUrl;
|
|
539
|
+
}
|
|
522
540
|
|
|
523
541
|
// src/sources/api-provider.ts
|
|
524
542
|
import { createWriteStream } from "fs";
|
|
@@ -529,6 +547,9 @@ import { pipeline } from "stream/promises";
|
|
|
529
547
|
|
|
530
548
|
// src/lib/api-v1-contract.ts
|
|
531
549
|
import { z as z3 } from "zod";
|
|
550
|
+
var primeUiPageSlugInputSchema = z3.string().refine((value) => value.trim().length > 0, {
|
|
551
|
+
message: "pageSlug must be a non-empty string"
|
|
552
|
+
});
|
|
532
553
|
var primeUiExportStatusSchema = z3.enum(
|
|
533
554
|
["in_progress", "completed", "failed"]
|
|
534
555
|
);
|
|
@@ -601,6 +622,14 @@ var primeUiComponentExportPageSchema = z3.object({
|
|
|
601
622
|
isReadyToExport: z3.boolean(),
|
|
602
623
|
manifest: primeUiExportPageManifestSchema
|
|
603
624
|
});
|
|
625
|
+
var primeUiComponentExportSelectedBlockSchema = z3.object({
|
|
626
|
+
blockId: z3.string(),
|
|
627
|
+
componentId: z3.string(),
|
|
628
|
+
contentKey: z3.string(),
|
|
629
|
+
occurrenceIndex: z3.number().int().positive(),
|
|
630
|
+
props: z3.record(z3.unknown()).nullable(),
|
|
631
|
+
slot: z3.string().nullable()
|
|
632
|
+
});
|
|
604
633
|
var primeUiProjectInfoSchema = z3.object(
|
|
605
634
|
{
|
|
606
635
|
projectId: z3.string(),
|
|
@@ -639,6 +668,115 @@ var primeUiPageGenerationTypeSchema = z3.enum([
|
|
|
639
668
|
"docs",
|
|
640
669
|
"legal"
|
|
641
670
|
]);
|
|
671
|
+
var primeUiComponentCandidateOperationSchema = z3.discriminatedUnion("type", [
|
|
672
|
+
z3.object({
|
|
673
|
+
type: z3.literal("append")
|
|
674
|
+
}),
|
|
675
|
+
z3.object({
|
|
676
|
+
type: z3.literal("insert"),
|
|
677
|
+
index: z3.number().int()
|
|
678
|
+
}),
|
|
679
|
+
z3.object({
|
|
680
|
+
type: z3.literal("replace"),
|
|
681
|
+
index: z3.number().int()
|
|
682
|
+
})
|
|
683
|
+
]);
|
|
684
|
+
var primeUiComponentCandidateConstraintsSchema = z3.object({
|
|
685
|
+
spreadDegree: z3.enum(["any-group", "same-group", "same-family"]).optional(),
|
|
686
|
+
allowedGroups: z3.array(z3.string()).optional(),
|
|
687
|
+
excludedGroups: z3.array(z3.string()).optional(),
|
|
688
|
+
excludeComponentIds: z3.array(z3.string()).optional()
|
|
689
|
+
});
|
|
690
|
+
var primeUiComponentCandidatesInputSchema = z3.object({
|
|
691
|
+
pageSlug: primeUiPageSlugInputSchema,
|
|
692
|
+
pageType: primeUiPageGenerationTypeSchema,
|
|
693
|
+
blocks: z3.array(
|
|
694
|
+
z3.object({
|
|
695
|
+
componentId: z3.string()
|
|
696
|
+
})
|
|
697
|
+
),
|
|
698
|
+
operation: primeUiComponentCandidateOperationSchema,
|
|
699
|
+
count: z3.number().int().positive().optional(),
|
|
700
|
+
constraints: primeUiComponentCandidateConstraintsSchema.optional()
|
|
701
|
+
});
|
|
702
|
+
var primeUiComponentCandidateRequestEchoSchema = z3.object({
|
|
703
|
+
pageSlug: z3.string(),
|
|
704
|
+
pageType: z3.string(),
|
|
705
|
+
operation: primeUiComponentCandidateOperationSchema,
|
|
706
|
+
count: z3.number()
|
|
707
|
+
});
|
|
708
|
+
var requiredUnknownSchema = z3.custom((value) => value !== void 0);
|
|
709
|
+
var primeUiComponentCandidateLayoutObjectSchema = z3.object({
|
|
710
|
+
container: requiredUnknownSchema,
|
|
711
|
+
textAlignment: requiredUnknownSchema,
|
|
712
|
+
bottomWeight: requiredUnknownSchema,
|
|
713
|
+
entryWidth: requiredUnknownSchema,
|
|
714
|
+
exitWidth: requiredUnknownSchema,
|
|
715
|
+
orientation: requiredUnknownSchema,
|
|
716
|
+
structure: requiredUnknownSchema
|
|
717
|
+
});
|
|
718
|
+
var primeUiComponentCandidateLayoutSchema = z3.custom(
|
|
719
|
+
(value) => primeUiComponentCandidateLayoutObjectSchema.safeParse(value).success
|
|
720
|
+
);
|
|
721
|
+
var primeUiComponentCandidateObjectSchema = z3.object({
|
|
722
|
+
componentId: z3.string(),
|
|
723
|
+
name: z3.string(),
|
|
724
|
+
group: z3.string(),
|
|
725
|
+
familyId: z3.string(),
|
|
726
|
+
uxScore: z3.number(),
|
|
727
|
+
insertionScore: z3.number(),
|
|
728
|
+
followingScore: z3.number(),
|
|
729
|
+
layout: primeUiComponentCandidateLayoutSchema,
|
|
730
|
+
defaultProps: requiredUnknownSchema,
|
|
731
|
+
exportReady: z3.boolean(),
|
|
732
|
+
copyHints: z3.object({
|
|
733
|
+
deliveryToolchain: z3.array(z3.string())
|
|
734
|
+
}),
|
|
735
|
+
description: z3.string().nullable().optional(),
|
|
736
|
+
functionality: z3.string().nullable().optional(),
|
|
737
|
+
impression: z3.string().nullable().optional(),
|
|
738
|
+
visualStyle: z3.unknown().optional(),
|
|
739
|
+
compactSchema: z3.string().nullable().optional(),
|
|
740
|
+
jsonSchema: z3.record(z3.unknown()).nullable().optional()
|
|
741
|
+
});
|
|
742
|
+
var primeUiComponentCandidateSchema = z3.custom(
|
|
743
|
+
(value) => primeUiComponentCandidateObjectSchema.safeParse(value).success
|
|
744
|
+
);
|
|
745
|
+
var primeUiComponentCandidatesResponseSchema = z3.object({
|
|
746
|
+
request: primeUiComponentCandidateRequestEchoSchema,
|
|
747
|
+
candidates: z3.array(primeUiComponentCandidateSchema)
|
|
748
|
+
});
|
|
749
|
+
var primeUiComponentPropsValidateInputSchema = z3.object({
|
|
750
|
+
blockId: z3.string().refine((value) => value.trim().length > 0, {
|
|
751
|
+
message: "blockId must be a non-empty string"
|
|
752
|
+
}),
|
|
753
|
+
pageSlug: primeUiPageSlugInputSchema,
|
|
754
|
+
componentId: z3.string(),
|
|
755
|
+
props: z3.record(z3.unknown())
|
|
756
|
+
});
|
|
757
|
+
var primeUiComponentPropsValidationErrorSchema = z3.object({
|
|
758
|
+
path: z3.string(),
|
|
759
|
+
message: z3.string()
|
|
760
|
+
});
|
|
761
|
+
var primeUiComponentPropsRenderCheckSchema = z3.object({
|
|
762
|
+
attempted: z3.boolean(),
|
|
763
|
+
passed: z3.boolean(),
|
|
764
|
+
message: z3.string()
|
|
765
|
+
});
|
|
766
|
+
var primeUiComponentPropsValidateResponseSchema = z3.object({
|
|
767
|
+
valid: z3.boolean(),
|
|
768
|
+
normalizedProps: z3.record(z3.unknown()).nullable(),
|
|
769
|
+
propsValidationId: z3.string().nullable(),
|
|
770
|
+
block: z3.object({
|
|
771
|
+
blockId: z3.string(),
|
|
772
|
+
componentId: z3.string(),
|
|
773
|
+
contentKey: z3.string(),
|
|
774
|
+
props: z3.record(z3.unknown())
|
|
775
|
+
}).nullable(),
|
|
776
|
+
errors: z3.array(primeUiComponentPropsValidationErrorSchema),
|
|
777
|
+
hints: z3.array(z3.string()),
|
|
778
|
+
renderCheck: primeUiComponentPropsRenderCheckSchema
|
|
779
|
+
});
|
|
642
780
|
var primeUiProjectApiWireframeStatusSchema = z3.enum(["pending", "generating", "ready", "error"]);
|
|
643
781
|
var primeUiProjectApiVariantSummarySchema = z3.object({
|
|
644
782
|
id: z3.string(),
|
|
@@ -867,6 +1005,7 @@ var primeUiExportManifestSchema = primeUiCreateExportResponseSchema;
|
|
|
867
1005
|
var primeUiComponentExportResponseSchema = z3.object({
|
|
868
1006
|
exportId: z3.string(),
|
|
869
1007
|
export: primeUiPostExportPayloadExportSchema,
|
|
1008
|
+
block: primeUiComponentExportSelectedBlockSchema.optional(),
|
|
870
1009
|
component: primeUiComponentExportComponentSchema,
|
|
871
1010
|
page: primeUiComponentExportPageSchema,
|
|
872
1011
|
pages: z3.array(primeUiComponentExportPageSchema)
|
|
@@ -963,6 +1102,16 @@ var normalizePrimeUiApiRoot = (rawBaseUrl) => {
|
|
|
963
1102
|
var buildPrimeUiApiUrl = (apiRoot, endpoint) => new URL(endpoint, apiRoot).toString();
|
|
964
1103
|
var isJsonContentType = (contentType) => contentType.includes("application/json") || contentType.includes("+json");
|
|
965
1104
|
var isZipContentType = (contentType) => ZIP_CONTENT_TYPES.some((allowedType) => contentType.includes(allowedType));
|
|
1105
|
+
function normalizePropsValidationId(propsValidationId) {
|
|
1106
|
+
if (typeof propsValidationId === "undefined") {
|
|
1107
|
+
return void 0;
|
|
1108
|
+
}
|
|
1109
|
+
const trimmed = propsValidationId.trim();
|
|
1110
|
+
if (!trimmed) {
|
|
1111
|
+
throw new Error("propsValidationId must be a non-empty string.");
|
|
1112
|
+
}
|
|
1113
|
+
return trimmed;
|
|
1114
|
+
}
|
|
966
1115
|
var looksLikeZipArchive = (buffer) => {
|
|
967
1116
|
if (buffer.length < 4) {
|
|
968
1117
|
return false;
|
|
@@ -1145,6 +1294,20 @@ var ApiProjectDataProvider = class {
|
|
|
1145
1294
|
primeUiProjectPageDetailsSchema
|
|
1146
1295
|
);
|
|
1147
1296
|
}
|
|
1297
|
+
async getComponentCandidates(input) {
|
|
1298
|
+
return this.requestJson(
|
|
1299
|
+
"component-planning/candidates",
|
|
1300
|
+
primeUiComponentCandidatesResponseSchema,
|
|
1301
|
+
this.buildJsonRequestInit(input)
|
|
1302
|
+
);
|
|
1303
|
+
}
|
|
1304
|
+
async validateComponentProps(input) {
|
|
1305
|
+
return this.requestJson(
|
|
1306
|
+
"component-planning/props/validate",
|
|
1307
|
+
primeUiComponentPropsValidateResponseSchema,
|
|
1308
|
+
this.buildJsonRequestInit(input)
|
|
1309
|
+
);
|
|
1310
|
+
}
|
|
1148
1311
|
async listExports() {
|
|
1149
1312
|
const response = await this.requestJson(
|
|
1150
1313
|
"project/exports",
|
|
@@ -1161,11 +1324,14 @@ var ApiProjectDataProvider = class {
|
|
|
1161
1324
|
}
|
|
1162
1325
|
);
|
|
1163
1326
|
}
|
|
1164
|
-
async createComponentExport(componentId) {
|
|
1327
|
+
async createComponentExport(componentId, options = {}) {
|
|
1328
|
+
const propsValidationId = normalizePropsValidationId(
|
|
1329
|
+
options.propsValidationId
|
|
1330
|
+
);
|
|
1165
1331
|
return this.requestJson(
|
|
1166
1332
|
`component-registry/components/${encodeURIComponent(componentId)}/exports`,
|
|
1167
1333
|
primeUiComponentExportResponseSchema,
|
|
1168
|
-
{
|
|
1334
|
+
propsValidationId ? this.buildJsonRequestInit({ propsValidationId }) : {
|
|
1169
1335
|
method: "POST"
|
|
1170
1336
|
}
|
|
1171
1337
|
);
|
|
@@ -1856,19 +2022,23 @@ async function runHealthCheck(options) {
|
|
|
1856
2022
|
apiKeyFromEnv: env.PRIMEUI_API_KEY
|
|
1857
2023
|
});
|
|
1858
2024
|
const configApiKeyState = resolvedProjectConfig ? "set" : configStatus === "missing" || configStatus === "unresolved" ? "missing" : "unknown";
|
|
1859
|
-
const
|
|
2025
|
+
const apiBaseUrlDetails = resolvePrimeUiApiBaseUrlDetails({
|
|
2026
|
+
projectConfig: resolvedProjectConfig?.projectConfig,
|
|
2027
|
+
baseUrlFromEnv: env.PRIMEUI_API_BASE_URL
|
|
2028
|
+
});
|
|
2029
|
+
const apiBaseUrlSource = apiBaseUrlDetails.source;
|
|
1860
2030
|
const defaultApiRoot = normalizePrimeUiApiRoot(DEFAULT_API_BASE_URL);
|
|
1861
2031
|
let apiRoot;
|
|
1862
2032
|
let projectInfoUrl;
|
|
1863
2033
|
let apiCheck;
|
|
1864
2034
|
try {
|
|
1865
|
-
apiRoot = normalizePrimeUiApiRoot(
|
|
2035
|
+
apiRoot = normalizePrimeUiApiRoot(apiBaseUrlDetails.baseUrl);
|
|
1866
2036
|
projectInfoUrl = buildPrimeUiApiUrl(apiRoot, "project");
|
|
1867
2037
|
} catch (error) {
|
|
1868
2038
|
apiCheck = {
|
|
1869
2039
|
status: "skipped",
|
|
1870
2040
|
apiBaseUrlSource,
|
|
1871
|
-
nonStandardBaseUrl: Boolean(
|
|
2041
|
+
nonStandardBaseUrl: Boolean(apiBaseUrlDetails.baseUrl?.trim()),
|
|
1872
2042
|
message: error instanceof Error ? error.message : String(error),
|
|
1873
2043
|
errorKind: "configuration"
|
|
1874
2044
|
};
|
|
@@ -1886,10 +2056,10 @@ async function runHealthCheck(options) {
|
|
|
1886
2056
|
} else {
|
|
1887
2057
|
const provider = options.createProvider?.({
|
|
1888
2058
|
apiKey: apiKeyDetails.apiKey,
|
|
1889
|
-
baseUrl:
|
|
2059
|
+
baseUrl: apiBaseUrlDetails.baseUrl
|
|
1890
2060
|
}) ?? new ApiProjectDataProvider({
|
|
1891
2061
|
apiKey: apiKeyDetails.apiKey,
|
|
1892
|
-
baseUrl:
|
|
2062
|
+
baseUrl: apiBaseUrlDetails.baseUrl
|
|
1893
2063
|
});
|
|
1894
2064
|
try {
|
|
1895
2065
|
await provider.getProjectInfo();
|
|
@@ -3782,6 +3952,11 @@ function isVirtualRouteFile(relativePath) {
|
|
|
3782
3952
|
const segments = relativePath.split("/");
|
|
3783
3953
|
return segments[0] === "src" && segments[1] === "app" && segments.includes(VIRTUAL_ROUTE_SEGMENT);
|
|
3784
3954
|
}
|
|
3955
|
+
function isVirtualComponentExportPageFile(relativePath) {
|
|
3956
|
+
const segments = relativePath.split("/");
|
|
3957
|
+
const virtualRouteIndex = segments.indexOf(VIRTUAL_ROUTE_SEGMENT);
|
|
3958
|
+
return isVirtualRouteFile(relativePath) && virtualRouteIndex >= 0 && segments.length === virtualRouteIndex + 3 && segments[virtualRouteIndex + 2] === "page.tsx";
|
|
3959
|
+
}
|
|
3785
3960
|
function getVirtualComponentRelativePath(relativePath, componentId) {
|
|
3786
3961
|
const prefix = `${COMPONENT_PAGES_PREFIX}${VIRTUAL_ROUTE_SEGMENT}/${componentId}/`;
|
|
3787
3962
|
if (!relativePath.startsWith(prefix)) {
|
|
@@ -3847,6 +4022,44 @@ function toImportPath(relativePath) {
|
|
|
3847
4022
|
const withoutIndex = withoutExtension.replace(/\/index$/u, "");
|
|
3848
4023
|
return `@/${withoutIndex.replace(/^src\//u, "")}`;
|
|
3849
4024
|
}
|
|
4025
|
+
function toPascalComponentName(componentId) {
|
|
4026
|
+
return componentId.split(/[^a-zA-Z0-9]+/u).filter(Boolean).map((part) => `${part.charAt(0).toUpperCase()}${part.slice(1)}`).join("");
|
|
4027
|
+
}
|
|
4028
|
+
function toVariableName(componentName) {
|
|
4029
|
+
if (!componentName) {
|
|
4030
|
+
return "componentProps";
|
|
4031
|
+
}
|
|
4032
|
+
return `${componentName.charAt(0).toLowerCase()}${componentName.slice(1)}Props`;
|
|
4033
|
+
}
|
|
4034
|
+
function toSafeCamelIdentifier(input, fallback) {
|
|
4035
|
+
const parts = input.trim().split(/[^a-zA-Z0-9]+/u).filter(Boolean);
|
|
4036
|
+
if (parts.length === 0) {
|
|
4037
|
+
return fallback;
|
|
4038
|
+
}
|
|
4039
|
+
const pascalName = parts.map((part) => {
|
|
4040
|
+
const normalizedPart = part.toLowerCase();
|
|
4041
|
+
return `${normalizedPart.charAt(0).toUpperCase()}${normalizedPart.slice(1)}`;
|
|
4042
|
+
}).join("");
|
|
4043
|
+
if (!pascalName) {
|
|
4044
|
+
return fallback;
|
|
4045
|
+
}
|
|
4046
|
+
if (/^[0-9]/u.test(pascalName)) {
|
|
4047
|
+
return `block${pascalName}`;
|
|
4048
|
+
}
|
|
4049
|
+
return `${pascalName.charAt(0).toLowerCase()}${pascalName.slice(1)}`;
|
|
4050
|
+
}
|
|
4051
|
+
function isDefaultComponentExportBlock(selectedBlock) {
|
|
4052
|
+
return selectedBlock.blockId === `component-export:${selectedBlock.componentId}:block`;
|
|
4053
|
+
}
|
|
4054
|
+
function toPropsVariableName(input) {
|
|
4055
|
+
if (isDefaultComponentExportBlock(input.selectedBlock)) {
|
|
4056
|
+
return toVariableName(input.componentName);
|
|
4057
|
+
}
|
|
4058
|
+
return `${toSafeCamelIdentifier(
|
|
4059
|
+
input.selectedBlock.blockId,
|
|
4060
|
+
input.componentName ? toVariableName(input.componentName).replace(/Props$/u, "") : "component"
|
|
4061
|
+
)}Props`;
|
|
4062
|
+
}
|
|
3850
4063
|
function escapeRegExp(value) {
|
|
3851
4064
|
return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
3852
4065
|
}
|
|
@@ -4086,6 +4299,113 @@ function buildMessage(input) {
|
|
|
4086
4299
|
);
|
|
4087
4300
|
return parts.join(" ");
|
|
4088
4301
|
}
|
|
4302
|
+
function getDefaultSelectedBlock(manifest) {
|
|
4303
|
+
const componentId = manifest.component.componentId;
|
|
4304
|
+
return {
|
|
4305
|
+
blockId: `component-export:${componentId}:block`,
|
|
4306
|
+
componentId,
|
|
4307
|
+
contentKey: componentId,
|
|
4308
|
+
occurrenceIndex: 1,
|
|
4309
|
+
props: null,
|
|
4310
|
+
slot: null
|
|
4311
|
+
};
|
|
4312
|
+
}
|
|
4313
|
+
function getSelectedBlock(manifest) {
|
|
4314
|
+
return manifest.block ?? getDefaultSelectedBlock(manifest);
|
|
4315
|
+
}
|
|
4316
|
+
function getVirtualRouteFile(manifestFiles) {
|
|
4317
|
+
return manifestFiles.find(isVirtualComponentExportPageFile) ?? manifestFiles.find(isVirtualRouteFile) ?? null;
|
|
4318
|
+
}
|
|
4319
|
+
function readBalancedObjectLiteral(input, startIndex) {
|
|
4320
|
+
if (input[startIndex] !== "{") {
|
|
4321
|
+
return null;
|
|
4322
|
+
}
|
|
4323
|
+
let depth = 0;
|
|
4324
|
+
let quote = null;
|
|
4325
|
+
let escaped = false;
|
|
4326
|
+
for (let index = startIndex; index < input.length; index += 1) {
|
|
4327
|
+
const char = input[index];
|
|
4328
|
+
if (escaped) {
|
|
4329
|
+
escaped = false;
|
|
4330
|
+
continue;
|
|
4331
|
+
}
|
|
4332
|
+
if (quote) {
|
|
4333
|
+
if (char === "\\") {
|
|
4334
|
+
escaped = true;
|
|
4335
|
+
continue;
|
|
4336
|
+
}
|
|
4337
|
+
if (char === quote) {
|
|
4338
|
+
quote = null;
|
|
4339
|
+
}
|
|
4340
|
+
continue;
|
|
4341
|
+
}
|
|
4342
|
+
if (char === '"' || char === "'" || char === "`") {
|
|
4343
|
+
quote = char;
|
|
4344
|
+
continue;
|
|
4345
|
+
}
|
|
4346
|
+
if (char === "{") {
|
|
4347
|
+
depth += 1;
|
|
4348
|
+
continue;
|
|
4349
|
+
}
|
|
4350
|
+
if (char !== "}") {
|
|
4351
|
+
continue;
|
|
4352
|
+
}
|
|
4353
|
+
depth -= 1;
|
|
4354
|
+
if (depth === 0) {
|
|
4355
|
+
return input.slice(startIndex, index + 1);
|
|
4356
|
+
}
|
|
4357
|
+
}
|
|
4358
|
+
return null;
|
|
4359
|
+
}
|
|
4360
|
+
function extractContentDataPropsCode(input) {
|
|
4361
|
+
const contentDataIndex = input.source.indexOf("const contentData");
|
|
4362
|
+
if (contentDataIndex < 0) {
|
|
4363
|
+
return null;
|
|
4364
|
+
}
|
|
4365
|
+
const keyPattern = new RegExp(
|
|
4366
|
+
`["']${escapeRegExp(input.contentKey)}["']\\s*:`,
|
|
4367
|
+
"u"
|
|
4368
|
+
);
|
|
4369
|
+
const keyMatch = keyPattern.exec(input.source.slice(contentDataIndex));
|
|
4370
|
+
if (!keyMatch) {
|
|
4371
|
+
return null;
|
|
4372
|
+
}
|
|
4373
|
+
const valueStartSearchIndex = contentDataIndex + keyMatch.index + keyMatch[0].length;
|
|
4374
|
+
const objectStartIndex = input.source.indexOf("{", valueStartSearchIndex);
|
|
4375
|
+
if (objectStartIndex < 0) {
|
|
4376
|
+
return null;
|
|
4377
|
+
}
|
|
4378
|
+
return readBalancedObjectLiteral(input.source, objectStartIndex);
|
|
4379
|
+
}
|
|
4380
|
+
async function buildRegistryComponentInsertion(input) {
|
|
4381
|
+
const componentName = toPascalComponentName(input.selectedBlock.componentId);
|
|
4382
|
+
const propsVariableName = toPropsVariableName({
|
|
4383
|
+
componentName,
|
|
4384
|
+
selectedBlock: input.selectedBlock
|
|
4385
|
+
});
|
|
4386
|
+
const virtualRouteFile = getVirtualRouteFile(input.manifestFiles);
|
|
4387
|
+
const referenceFiles = virtualRouteFile ? [virtualRouteFile] : [];
|
|
4388
|
+
let materializedPropsCode = input.selectedBlock.props ? JSON.stringify(input.selectedBlock.props, null, 2) : "{}";
|
|
4389
|
+
if (virtualRouteFile) {
|
|
4390
|
+
try {
|
|
4391
|
+
const virtualRouteSource = await readFile7(
|
|
4392
|
+
path13.join(input.exportPath, virtualRouteFile),
|
|
4393
|
+
"utf-8"
|
|
4394
|
+
);
|
|
4395
|
+
materializedPropsCode = extractContentDataPropsCode({
|
|
4396
|
+
source: virtualRouteSource,
|
|
4397
|
+
contentKey: input.selectedBlock.contentKey
|
|
4398
|
+
}) ?? materializedPropsCode;
|
|
4399
|
+
} catch {
|
|
4400
|
+
}
|
|
4401
|
+
}
|
|
4402
|
+
return {
|
|
4403
|
+
imports: [`import ${componentName} from "${input.componentImportPath}";`],
|
|
4404
|
+
propsCode: `const ${propsVariableName} = ${materializedPropsCode};`,
|
|
4405
|
+
jsx: `<${componentName} {...${propsVariableName}} />`,
|
|
4406
|
+
referenceFiles
|
|
4407
|
+
};
|
|
4408
|
+
}
|
|
4089
4409
|
async function copyRegistryComponentFromExport(input) {
|
|
4090
4410
|
const normalizedComponentId = normalizeComponentId(input.componentId);
|
|
4091
4411
|
const { exportId, exportPath } = await resolveSingleExportDirectory(
|
|
@@ -4160,7 +4480,9 @@ async function copyRegistryComponentFromExport(input) {
|
|
|
4160
4480
|
graphInternalFiles,
|
|
4161
4481
|
referencedPublicFiles
|
|
4162
4482
|
});
|
|
4163
|
-
const copyableSourceFiles = fileTransfers.map(
|
|
4483
|
+
const copyableSourceFiles = fileTransfers.map(
|
|
4484
|
+
(transfer) => transfer.sourcePath
|
|
4485
|
+
);
|
|
4164
4486
|
const copyableFiles = fileTransfers.map((transfer) => transfer.targetPath);
|
|
4165
4487
|
const transferBySourcePath = new Map(
|
|
4166
4488
|
fileTransfers.map((transfer) => [transfer.sourcePath, transfer])
|
|
@@ -4176,6 +4498,13 @@ async function copyRegistryComponentFromExport(input) {
|
|
|
4176
4498
|
componentId: normalizedComponentId,
|
|
4177
4499
|
copyableFiles: copyableSourceFiles
|
|
4178
4500
|
});
|
|
4501
|
+
const selectedBlock = getSelectedBlock(manifest);
|
|
4502
|
+
const insertion = await buildRegistryComponentInsertion({
|
|
4503
|
+
componentImportPath,
|
|
4504
|
+
exportPath,
|
|
4505
|
+
manifestFiles,
|
|
4506
|
+
selectedBlock
|
|
4507
|
+
});
|
|
4179
4508
|
const candidateFiles = await resolveManifestCandidateFiles({
|
|
4180
4509
|
exportPath,
|
|
4181
4510
|
manifestOwnerLabel: `registry component "${normalizedComponentId}"`,
|
|
@@ -4267,8 +4596,10 @@ async function copyRegistryComponentFromExport(input) {
|
|
|
4267
4596
|
exportId,
|
|
4268
4597
|
componentId: normalizedComponentId,
|
|
4269
4598
|
componentImportPath,
|
|
4599
|
+
insertion,
|
|
4270
4600
|
manifestFiles,
|
|
4271
4601
|
copyableFiles,
|
|
4602
|
+
selectedBlock,
|
|
4272
4603
|
skippedFiles,
|
|
4273
4604
|
conflicts: sortedConflictEntries,
|
|
4274
4605
|
missingManifestFiles: missingManifestFileList
|
|
@@ -4305,8 +4636,10 @@ async function copyRegistryComponentFromExport(input) {
|
|
|
4305
4636
|
manifestPath,
|
|
4306
4637
|
component: manifest.component,
|
|
4307
4638
|
componentImportPath,
|
|
4639
|
+
insertion,
|
|
4308
4640
|
manifestFiles,
|
|
4309
4641
|
copyableFiles,
|
|
4642
|
+
selectedBlock,
|
|
4310
4643
|
newFiles: sortedNewFiles,
|
|
4311
4644
|
identicalFiles: sortedIdenticalFiles,
|
|
4312
4645
|
conflictFiles: sortedConflictFiles,
|
|
@@ -4510,6 +4843,12 @@ var ProjectSyncService = class {
|
|
|
4510
4843
|
notes: guidanceNotes
|
|
4511
4844
|
};
|
|
4512
4845
|
}
|
|
4846
|
+
async getComponentCandidates(input, _context) {
|
|
4847
|
+
return this.provider.getComponentCandidates(input);
|
|
4848
|
+
}
|
|
4849
|
+
async validateComponentProps(input, _context) {
|
|
4850
|
+
return this.provider.validateComponentProps(input);
|
|
4851
|
+
}
|
|
4513
4852
|
async listExports(_context) {
|
|
4514
4853
|
await this.ensureTempLayout();
|
|
4515
4854
|
return this.provider.listExports();
|
|
@@ -4528,9 +4867,11 @@ var ProjectSyncService = class {
|
|
|
4528
4867
|
}
|
|
4529
4868
|
};
|
|
4530
4869
|
}
|
|
4531
|
-
async createComponentExport(componentId, _context) {
|
|
4870
|
+
async createComponentExport(componentId, options = {}, _context) {
|
|
4532
4871
|
await this.ensureTempLayout();
|
|
4533
|
-
const result = await this.provider.createComponentExport(componentId
|
|
4872
|
+
const result = await this.provider.createComponentExport(componentId, {
|
|
4873
|
+
propsValidationId: options.propsValidationId
|
|
4874
|
+
});
|
|
4534
4875
|
const manifestPath = buildManifestPath(this.exportsRoot, result.export.id);
|
|
4535
4876
|
await writeUtf8(manifestPath, `${JSON.stringify(result, null, 2)}
|
|
4536
4877
|
`);
|
|
@@ -4768,10 +5109,14 @@ var LazyProjectSyncSource = class {
|
|
|
4768
5109
|
projectConfig: resolvedProjectConfig.projectConfig,
|
|
4769
5110
|
apiKeyFromEnv: this.env.PRIMEUI_API_KEY
|
|
4770
5111
|
});
|
|
5112
|
+
const baseUrl = resolvePrimeUiApiBaseUrl({
|
|
5113
|
+
projectConfig: resolvedProjectConfig.projectConfig,
|
|
5114
|
+
baseUrlFromEnv: this.env.PRIMEUI_API_BASE_URL
|
|
5115
|
+
});
|
|
4771
5116
|
this.stickyProjectRoot = projectRoot;
|
|
4772
5117
|
const provider = this.createProvider({
|
|
4773
5118
|
apiKey,
|
|
4774
|
-
baseUrl
|
|
5119
|
+
baseUrl
|
|
4775
5120
|
});
|
|
4776
5121
|
return new ProjectSyncService({
|
|
4777
5122
|
projectRoot,
|
|
@@ -4954,6 +5299,24 @@ var LazyProjectSyncSource = class {
|
|
|
4954
5299
|
(service) => service.syncSearchEnvironment(environmentSlug, context)
|
|
4955
5300
|
);
|
|
4956
5301
|
}
|
|
5302
|
+
async getComponentCandidates(input, context) {
|
|
5303
|
+
return this.withService(
|
|
5304
|
+
context,
|
|
5305
|
+
(service) => service.getComponentCandidates(input, context),
|
|
5306
|
+
{
|
|
5307
|
+
requireTargetProjectRoot: false
|
|
5308
|
+
}
|
|
5309
|
+
);
|
|
5310
|
+
}
|
|
5311
|
+
async validateComponentProps(input, context) {
|
|
5312
|
+
return this.withService(
|
|
5313
|
+
context,
|
|
5314
|
+
(service) => service.validateComponentProps(input, context),
|
|
5315
|
+
{
|
|
5316
|
+
requireTargetProjectRoot: false
|
|
5317
|
+
}
|
|
5318
|
+
);
|
|
5319
|
+
}
|
|
4957
5320
|
async listExports(context) {
|
|
4958
5321
|
return this.withService(context, (service) => service.listExports(context));
|
|
4959
5322
|
}
|
|
@@ -4963,10 +5326,10 @@ var LazyProjectSyncSource = class {
|
|
|
4963
5326
|
(service) => service.createExport(context)
|
|
4964
5327
|
);
|
|
4965
5328
|
}
|
|
4966
|
-
async createComponentExport(componentId, context) {
|
|
5329
|
+
async createComponentExport(componentId, options, context) {
|
|
4967
5330
|
return this.withService(
|
|
4968
5331
|
context,
|
|
4969
|
-
(service) => service.createComponentExport(componentId, context)
|
|
5332
|
+
(service) => service.createComponentExport(componentId, options, context)
|
|
4970
5333
|
);
|
|
4971
5334
|
}
|
|
4972
5335
|
async downloadExportById(id, context) {
|
|
@@ -5186,6 +5549,16 @@ var copyComponentGuidanceSchema = z4.object({
|
|
|
5186
5549
|
requiredActions: z4.array(z4.string()).describe("Concrete next actions for finishing component transfer."),
|
|
5187
5550
|
notes: z4.array(z4.string()).describe("Important semantics and caveats for this transfer result.")
|
|
5188
5551
|
});
|
|
5552
|
+
var registryComponentInsertionSchema = z4.object({
|
|
5553
|
+
imports: z4.array(z4.string()).describe("Import statements needed for inserting the copied component."),
|
|
5554
|
+
propsCode: z4.string().describe(
|
|
5555
|
+
"Materialized props source derived from the downloaded virtual component export."
|
|
5556
|
+
),
|
|
5557
|
+
jsx: z4.string().describe("JSX snippet for rendering the materialized component instance."),
|
|
5558
|
+
referenceFiles: z4.array(z4.string()).describe(
|
|
5559
|
+
"Downloaded export files used as the source of truth for materialized insertion."
|
|
5560
|
+
)
|
|
5561
|
+
});
|
|
5189
5562
|
var pageDetailsSchema = pageSchema.extend({
|
|
5190
5563
|
pageInstruction: z4.string().nullable().describe(
|
|
5191
5564
|
"Current instruction text for the active page variant. Null when no active variant is set."
|
|
@@ -5248,7 +5621,8 @@ ${WORKFLOW_SUMMARY}
|
|
|
5248
5621
|
|
|
5249
5622
|
ADDITIONAL CAPABILITIES:
|
|
5250
5623
|
- PrimeUI MCP also exposes atomic external API tools for project description, project pages, page variants, active-variant selection, and issue reports.
|
|
5251
|
-
-
|
|
5624
|
+
- PrimeUI MCP also exposes component planning tools such as component_candidates_get and component_props_validate for exported-project page building.
|
|
5625
|
+
- These additional tools are OPTIONAL capabilities for extended scenarios.
|
|
5252
5626
|
- They are NOT part of the primary import/export workflow above.
|
|
5253
5627
|
- Do not replace get_project_info/create_export/download_export/copy_* with the additional API tools when the user wants the standard page import/export flow.
|
|
5254
5628
|
|
|
@@ -5473,6 +5847,7 @@ WHEN TO USE: Use this only for the component-registry import track when the user
|
|
|
5473
5847
|
AFTER CALLING:
|
|
5474
5848
|
- Verify component.componentId matches the requested componentId.
|
|
5475
5849
|
- Verify component.isReadyToExport is true and page.manifest.files is present.
|
|
5850
|
+
- Pass propsValidationId from component_props_validate when exporting a validated instance. Omit it only for the intentional default-props component export path.
|
|
5476
5851
|
- Local component sidecar manifest is saved to .primeui/temp/exports/[exportId].manifest.json.
|
|
5477
5852
|
- Use the returned export ID to call download_component_export.
|
|
5478
5853
|
- Use copy_registry_component after download_component_export for this component-track manifest. Do not use page copy tools for component-track manifests.
|
|
@@ -5481,7 +5856,10 @@ AFTER CALLING:
|
|
|
5481
5856
|
${WORKFLOW_SUMMARY}`,
|
|
5482
5857
|
inputSchema: {
|
|
5483
5858
|
projectRoot: projectRootInputSchema,
|
|
5484
|
-
componentId: z4.string().min(1).describe("PrimeUI component registry identifier to export.")
|
|
5859
|
+
componentId: z4.string().min(1).describe("PrimeUI component registry identifier to export."),
|
|
5860
|
+
propsValidationId: z4.string().trim().min(1).optional().describe(
|
|
5861
|
+
"Optional props validation handoff id returned by component_props_validate. Omit to export registry defaultProps."
|
|
5862
|
+
)
|
|
5485
5863
|
},
|
|
5486
5864
|
outputSchema: z4.object({
|
|
5487
5865
|
exportId: z4.string().describe(
|
|
@@ -5500,6 +5878,9 @@ ${WORKFLOW_SUMMARY}`,
|
|
|
5500
5878
|
exportables: z4.array(exportableSchema).describe("Shared exportables included in this export payload.")
|
|
5501
5879
|
}).describe("Created component export summary."),
|
|
5502
5880
|
component: componentExportComponentSchema,
|
|
5881
|
+
block: copyComponentSelectedBlockSchema.optional().describe(
|
|
5882
|
+
"Selected virtual component-export block metadata when the export used a propsValidationId handoff."
|
|
5883
|
+
),
|
|
5503
5884
|
page: componentExportPageSchema.describe(
|
|
5504
5885
|
"Virtual page manifest for this component export."
|
|
5505
5886
|
),
|
|
@@ -5813,6 +6194,7 @@ BEHAVIOR:
|
|
|
5813
6194
|
- Copies only the selected registry component import graph, narrowly referenced public assets, and safe support files from the component sidecar manifest/export.
|
|
5814
6195
|
- Remaps component-local files into src/components/shared/** and returns componentImportPath for manual insertion.
|
|
5815
6196
|
- Skips virtual route files that include __primeui-component-export, because those are reference/insertion hints and must not be installed as normal app routes.
|
|
6197
|
+
- Returns selectedBlock and insertion artifacts derived from the downloaded virtual component export. Treat insertion.propsCode and insertion.jsx as the materialized instance source of truth.
|
|
5816
6198
|
- Skips app/search/layout/header/footer/env/project-shell files instead of copying whole exportable buckets.
|
|
5817
6199
|
- Never copies package.json directly. package.json is used only to add missing dependency entries and report dependency version conflicts.
|
|
5818
6200
|
- Keeps safe support files on their natural target paths, such as src/components/ui/**, src/lib/**, src/types/**, and src/contexts/**.
|
|
@@ -5849,6 +6231,12 @@ ${WORKFLOW_SUMMARY}`,
|
|
|
5849
6231
|
componentImportPath: z4.string().describe(
|
|
5850
6232
|
"Canonical import path for the copied registry component entrypoint, for example @/components/shared/hero--pricing."
|
|
5851
6233
|
),
|
|
6234
|
+
selectedBlock: copyComponentSelectedBlockSchema.describe(
|
|
6235
|
+
"Selected virtual component-export block metadata. First-instance contentKey semantics match page export."
|
|
6236
|
+
),
|
|
6237
|
+
insertion: registryComponentInsertionSchema.describe(
|
|
6238
|
+
"Materialized insertion artifact for adding this component instance to a real local page."
|
|
6239
|
+
),
|
|
5852
6240
|
manifestFiles: z4.array(z4.string()).describe(
|
|
5853
6241
|
"Normalized component sidecar manifest files considered by the copy service."
|
|
5854
6242
|
),
|
|
@@ -6042,6 +6430,136 @@ var pageGenerationTypeSchema = z4.enum([
|
|
|
6042
6430
|
]).describe(
|
|
6043
6431
|
"Supported PrimeUI page type. Must match the external API page type enum."
|
|
6044
6432
|
);
|
|
6433
|
+
var componentCandidateOperationSchema = z4.discriminatedUnion("type", [
|
|
6434
|
+
z4.object({
|
|
6435
|
+
type: z4.literal("append")
|
|
6436
|
+
}),
|
|
6437
|
+
z4.object({
|
|
6438
|
+
type: z4.literal("insert"),
|
|
6439
|
+
index: z4.number().int().describe("Zero-based insertion index in the ordered blocks list.")
|
|
6440
|
+
}),
|
|
6441
|
+
z4.object({
|
|
6442
|
+
type: z4.literal("replace"),
|
|
6443
|
+
index: z4.number().int().describe("Zero-based index of the block being replaced.")
|
|
6444
|
+
})
|
|
6445
|
+
]);
|
|
6446
|
+
var componentCandidatesGetInputSchema = z4.object({
|
|
6447
|
+
projectRoot: projectRootInputSchema,
|
|
6448
|
+
pageSlug: z4.string().refine((value) => value.trim().length > 0, {
|
|
6449
|
+
message: "pageSlug must be a non-empty string"
|
|
6450
|
+
}).describe(
|
|
6451
|
+
"Stable PrimeUI page slug used for candidate scoring and automatic diagnostics, for example '/pricing'."
|
|
6452
|
+
),
|
|
6453
|
+
pageType: pageGenerationTypeSchema,
|
|
6454
|
+
blocks: z4.array(
|
|
6455
|
+
z4.object({
|
|
6456
|
+
componentId: z4.string().describe("PrimeUI component id already present in page order.")
|
|
6457
|
+
})
|
|
6458
|
+
).describe(
|
|
6459
|
+
"Current ordered page composition before applying the requested operation."
|
|
6460
|
+
),
|
|
6461
|
+
operation: componentCandidateOperationSchema.optional().default({ type: "append" }).describe(
|
|
6462
|
+
"Candidate placement operation. Omit for the normal append flow."
|
|
6463
|
+
),
|
|
6464
|
+
count: z4.number().int().positive().optional().describe("Optional maximum candidate count. Studio defaults to 8."),
|
|
6465
|
+
constraints: z4.object({
|
|
6466
|
+
spreadDegree: z4.enum(["any-group", "same-group", "same-family"]).optional().describe("Optional UX scoring spread override."),
|
|
6467
|
+
allowedGroups: z4.array(z4.string()).optional().describe("Optional allow-list of candidate groups."),
|
|
6468
|
+
excludedGroups: z4.array(z4.string()).optional().describe("Optional deny-list of candidate groups."),
|
|
6469
|
+
excludeComponentIds: z4.array(z4.string()).optional().describe("Optional component ids to remove from the candidate pool.")
|
|
6470
|
+
}).optional().describe("Optional advanced candidate pool and spread constraints.")
|
|
6471
|
+
});
|
|
6472
|
+
var componentCandidatesGetValidationSchema = componentCandidatesGetInputSchema;
|
|
6473
|
+
var componentPropsValidateInputSchema = z4.object({
|
|
6474
|
+
projectRoot: projectRootInputSchema,
|
|
6475
|
+
pageSlug: z4.string().refine((value) => value.trim().length > 0, {
|
|
6476
|
+
message: "pageSlug must be a non-empty string"
|
|
6477
|
+
}).describe(
|
|
6478
|
+
"Stable PrimeUI page slug used for validation diagnostics, for example '/pricing'. Use the same pageSlug as candidate retrieval."
|
|
6479
|
+
),
|
|
6480
|
+
componentId: z4.string().describe("PrimeUI component registry identifier selected by the agent."),
|
|
6481
|
+
blockId: z4.string().trim().min(1).describe(
|
|
6482
|
+
"Stable local block identifier for this planned component instance. Required for propsValidationId handoff records."
|
|
6483
|
+
),
|
|
6484
|
+
props: z4.record(z4.unknown()).describe(
|
|
6485
|
+
"Agent-authored props payload to validate against PrimeUI's registry schema."
|
|
6486
|
+
)
|
|
6487
|
+
});
|
|
6488
|
+
var componentPropsValidateValidationSchema = componentPropsValidateInputSchema;
|
|
6489
|
+
var componentCandidateLayoutSchema = z4.object({
|
|
6490
|
+
container: z4.unknown().describe("Layout container metadata."),
|
|
6491
|
+
textAlignment: z4.unknown().describe("Text alignment metadata."),
|
|
6492
|
+
bottomWeight: z4.unknown().describe("Bottom visual weight metadata."),
|
|
6493
|
+
entryWidth: z4.unknown().describe("Incoming width rhythm metadata."),
|
|
6494
|
+
exitWidth: z4.unknown().describe("Outgoing width rhythm metadata."),
|
|
6495
|
+
orientation: z4.unknown().describe("Optional orientation metadata."),
|
|
6496
|
+
structure: z4.unknown().describe("Optional structure metadata.")
|
|
6497
|
+
});
|
|
6498
|
+
var componentCandidateSchema = z4.object({
|
|
6499
|
+
componentId: z4.string().describe("PrimeUI component registry identifier to choose or export."),
|
|
6500
|
+
name: z4.string().describe("Human-readable component name."),
|
|
6501
|
+
group: z4.string().describe("Component group used by candidate scoring."),
|
|
6502
|
+
familyId: z4.string().describe("Component family identifier from catalog."),
|
|
6503
|
+
uxScore: z4.number().describe("Total UX score used for ranking."),
|
|
6504
|
+
insertionScore: z4.number().describe("Score for inserting this candidate at the requested position."),
|
|
6505
|
+
followingScore: z4.number().describe("Neighbor compatibility score with the following block."),
|
|
6506
|
+
layout: componentCandidateLayoutSchema.describe(
|
|
6507
|
+
"Layout metadata useful for choosing visual rhythm."
|
|
6508
|
+
),
|
|
6509
|
+
defaultProps: z4.unknown().describe("Registry default props, when available from PrimeUI."),
|
|
6510
|
+
exportReady: z4.boolean().describe("True when the component is expected to be exportable."),
|
|
6511
|
+
copyHints: z4.object({
|
|
6512
|
+
deliveryToolchain: z4.array(z4.string()).describe(
|
|
6513
|
+
"Recommended tool sequence for delivering this registry component locally."
|
|
6514
|
+
)
|
|
6515
|
+
}).describe("Machine-readable delivery hints for the selected candidate."),
|
|
6516
|
+
description: z4.string().nullable().optional(),
|
|
6517
|
+
functionality: z4.string().nullable().optional(),
|
|
6518
|
+
impression: z4.string().nullable().optional(),
|
|
6519
|
+
visualStyle: z4.unknown().optional(),
|
|
6520
|
+
compactSchema: z4.string().nullable().optional(),
|
|
6521
|
+
jsonSchema: z4.record(z4.unknown()).nullable().optional()
|
|
6522
|
+
});
|
|
6523
|
+
var componentCandidatesGetOutputSchema = z4.object({
|
|
6524
|
+
request: z4.object({
|
|
6525
|
+
pageSlug: z4.string(),
|
|
6526
|
+
pageType: z4.string(),
|
|
6527
|
+
operation: componentCandidateOperationSchema,
|
|
6528
|
+
count: z4.number()
|
|
6529
|
+
}).describe("Normalized request echo returned by PrimeUI."),
|
|
6530
|
+
candidates: z4.array(componentCandidateSchema).describe("Ranked rich candidate shortlist returned by PrimeUI.")
|
|
6531
|
+
});
|
|
6532
|
+
var componentPropsValidationErrorSchema = z4.object({
|
|
6533
|
+
path: z4.string().describe("JSON path or root path for the invalid props location."),
|
|
6534
|
+
message: z4.string().describe("Actionable validation message returned by PrimeUI.")
|
|
6535
|
+
});
|
|
6536
|
+
var componentPropsRenderCheckSchema = z4.object({
|
|
6537
|
+
attempted: z4.boolean().describe("True when PrimeUI attempted a render smoke check."),
|
|
6538
|
+
passed: z4.boolean().describe("True when the render smoke check passed."),
|
|
6539
|
+
message: z4.string().describe("Human-readable render check status or skip reason.")
|
|
6540
|
+
});
|
|
6541
|
+
var componentPropsValidateOutputSchema = z4.object({
|
|
6542
|
+
valid: z4.boolean().describe("True when props passed schema validation."),
|
|
6543
|
+
normalizedProps: z4.record(z4.unknown()).nullable().describe(
|
|
6544
|
+
"Props normalized by PrimeUI when valid; null when validation failed."
|
|
6545
|
+
),
|
|
6546
|
+
propsValidationId: z4.string().nullable().describe(
|
|
6547
|
+
"Durable validation handoff id for create_component_export; null when props are invalid."
|
|
6548
|
+
),
|
|
6549
|
+
block: z4.object({
|
|
6550
|
+
blockId: z4.string(),
|
|
6551
|
+
componentId: z4.string(),
|
|
6552
|
+
contentKey: z4.string(),
|
|
6553
|
+
props: z4.record(z4.unknown())
|
|
6554
|
+
}).nullable().describe(
|
|
6555
|
+
"Selected validated block identity and normalized props; null when props are invalid."
|
|
6556
|
+
),
|
|
6557
|
+
errors: z4.array(componentPropsValidationErrorSchema).describe("Structured validation errors for invalid props."),
|
|
6558
|
+
hints: z4.array(z4.string()).describe("Agent-facing guidance for correcting invalid props."),
|
|
6559
|
+
renderCheck: componentPropsRenderCheckSchema.describe(
|
|
6560
|
+
"Optional render-smoke status returned by PrimeUI."
|
|
6561
|
+
)
|
|
6562
|
+
});
|
|
6045
6563
|
var projectApiPageResourceSchema = z4.object({
|
|
6046
6564
|
id: z4.string().describe("Stable PrimeUI page identifier."),
|
|
6047
6565
|
title: z4.string().describe("Human-readable page title."),
|
|
@@ -6475,6 +6993,51 @@ WHEN TO USE:
|
|
|
6475
6993
|
openWorldHint: true
|
|
6476
6994
|
}
|
|
6477
6995
|
};
|
|
6996
|
+
var toolComponentCandidatesGet = {
|
|
6997
|
+
title: "PrimeUI Component Candidates Get",
|
|
6998
|
+
description: `External planning helper. Returns a ranked rich candidate shortlist for adding, inserting, or replacing one PrimeUI component in an exported-project page composition.
|
|
6999
|
+
|
|
7000
|
+
WHEN TO USE:
|
|
7001
|
+
- Use this when building or editing a local exported-project page and you need PrimeUI scoring guidance for which componentId to choose next.
|
|
7002
|
+
- The normal flow is append: pass the current ordered blocks and omit operation, which defaults to { "type": "append" }.
|
|
7003
|
+
- Use insert or replace only when the caller is intentionally editing a specific position in the ordered blocks list.
|
|
7004
|
+
- Use the returned copyHints.deliveryToolchain when the chosen candidate must be delivered locally: create_component_export, download_component_export, then copy_registry_component.
|
|
7005
|
+
|
|
7006
|
+
AFTER CALLING:
|
|
7007
|
+
- Choose from candidates using uxScore, insertionScore, followingScore, group/family/layout rhythm, descriptions, defaults, and schemas.
|
|
7008
|
+
- Do not mutate Prime page state from this tool result. This is planning guidance only.
|
|
7009
|
+
- Keep the same pageSlug across later planning and validation calls so PrimeUI diagnostics stay correlated.`,
|
|
7010
|
+
inputSchema: componentCandidatesGetInputSchema,
|
|
7011
|
+
outputSchema: componentCandidatesGetOutputSchema,
|
|
7012
|
+
annotations: {
|
|
7013
|
+
readOnlyHint: true,
|
|
7014
|
+
destructiveHint: false,
|
|
7015
|
+
idempotentHint: true,
|
|
7016
|
+
openWorldHint: true
|
|
7017
|
+
}
|
|
7018
|
+
};
|
|
7019
|
+
var toolComponentPropsValidate = {
|
|
7020
|
+
title: "PrimeUI Component Props Validate",
|
|
7021
|
+
description: `External planning helper. Validates agent-authored props for one selected PrimeUI component before editing local exported-project files.
|
|
7022
|
+
|
|
7023
|
+
WHEN TO USE:
|
|
7024
|
+
- Use this after choosing a component candidate and drafting props from the user's brief, candidate metadata, defaultProps, compactSchema, or jsonSchema.
|
|
7025
|
+
- Keep pageSlug stable across candidate retrieval and validation so PrimeUI diagnostics stay correlated.
|
|
7026
|
+
- Treat valid: false as actionable feedback, not a transport failure. Fix the props from errors and hints, then call this tool again.
|
|
7027
|
+
|
|
7028
|
+
AFTER CALLING:
|
|
7029
|
+
- If valid is true, pass propsValidationId to create_component_export so copy_registry_component can return materialized insertion artifacts.
|
|
7030
|
+
- If valid is false, correct props using errors[].path, errors[].message, and hints before editing local files.
|
|
7031
|
+
- Do not mutate Prime page state from this tool result. This is validation guidance only.`,
|
|
7032
|
+
inputSchema: componentPropsValidateInputSchema,
|
|
7033
|
+
outputSchema: componentPropsValidateOutputSchema,
|
|
7034
|
+
annotations: {
|
|
7035
|
+
readOnlyHint: true,
|
|
7036
|
+
destructiveHint: false,
|
|
7037
|
+
idempotentHint: true,
|
|
7038
|
+
openWorldHint: true
|
|
7039
|
+
}
|
|
7040
|
+
};
|
|
6478
7041
|
var toolProjectIssueReportSubmit = {
|
|
6479
7042
|
title: "PrimeUI Project Issue Report Submit",
|
|
6480
7043
|
description: `Atomic external API helper. Submits an issue report for the scoped PrimeUI project.
|
|
@@ -6885,6 +7448,32 @@ function createPrimeUiMcpServer(source) {
|
|
|
6885
7448
|
}
|
|
6886
7449
|
}
|
|
6887
7450
|
);
|
|
7451
|
+
server.registerTool(
|
|
7452
|
+
"component_candidates_get",
|
|
7453
|
+
toolComponentCandidatesGet,
|
|
7454
|
+
async (args) => {
|
|
7455
|
+
try {
|
|
7456
|
+
const { projectRoot, ...input } = componentCandidatesGetValidationSchema.parse(args);
|
|
7457
|
+
const result = await source.getComponentCandidates(input, { projectRoot });
|
|
7458
|
+
return okResult("component_candidates_get", result);
|
|
7459
|
+
} catch (error) {
|
|
7460
|
+
return errorResult(error);
|
|
7461
|
+
}
|
|
7462
|
+
}
|
|
7463
|
+
);
|
|
7464
|
+
server.registerTool(
|
|
7465
|
+
"component_props_validate",
|
|
7466
|
+
toolComponentPropsValidate,
|
|
7467
|
+
async (args) => {
|
|
7468
|
+
try {
|
|
7469
|
+
const { projectRoot, ...input } = componentPropsValidateValidationSchema.parse(args);
|
|
7470
|
+
const result = await source.validateComponentProps(input, { projectRoot });
|
|
7471
|
+
return okResult("component_props_validate", result);
|
|
7472
|
+
} catch (error) {
|
|
7473
|
+
return errorResult(error);
|
|
7474
|
+
}
|
|
7475
|
+
}
|
|
7476
|
+
);
|
|
6888
7477
|
server.registerTool(
|
|
6889
7478
|
"list_exports",
|
|
6890
7479
|
toolListExports,
|
|
@@ -6918,11 +7507,17 @@ function createPrimeUiMcpServer(source) {
|
|
|
6918
7507
|
server.registerTool(
|
|
6919
7508
|
"create_component_export",
|
|
6920
7509
|
toolCreateComponentExport,
|
|
6921
|
-
async ({
|
|
7510
|
+
async ({
|
|
7511
|
+
componentId,
|
|
7512
|
+
projectRoot,
|
|
7513
|
+
propsValidationId
|
|
7514
|
+
}) => {
|
|
6922
7515
|
try {
|
|
6923
|
-
const result = await source.createComponentExport(
|
|
6924
|
-
|
|
6925
|
-
|
|
7516
|
+
const result = await source.createComponentExport(
|
|
7517
|
+
componentId,
|
|
7518
|
+
{ propsValidationId },
|
|
7519
|
+
{ projectRoot }
|
|
7520
|
+
);
|
|
6926
7521
|
return okResult("create_component_export", result);
|
|
6927
7522
|
} catch (error) {
|
|
6928
7523
|
return errorResult(error);
|