@primeuicom/mcp 1.2.1 → 1.2.3
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 +607 -30
- package/dist/service.js.map +1 -1
- package/package.json +12 -13
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
|
);
|
|
@@ -639,6 +660,105 @@ var primeUiPageGenerationTypeSchema = z3.enum([
|
|
|
639
660
|
"docs",
|
|
640
661
|
"legal"
|
|
641
662
|
]);
|
|
663
|
+
var primeUiComponentCandidateOperationSchema = z3.discriminatedUnion("type", [
|
|
664
|
+
z3.object({
|
|
665
|
+
type: z3.literal("append")
|
|
666
|
+
}),
|
|
667
|
+
z3.object({
|
|
668
|
+
type: z3.literal("insert"),
|
|
669
|
+
index: z3.number().int()
|
|
670
|
+
}),
|
|
671
|
+
z3.object({
|
|
672
|
+
type: z3.literal("replace"),
|
|
673
|
+
index: z3.number().int()
|
|
674
|
+
})
|
|
675
|
+
]);
|
|
676
|
+
var primeUiComponentCandidateConstraintsSchema = z3.object({
|
|
677
|
+
spreadDegree: z3.enum(["any-group", "same-group", "same-family"]).optional(),
|
|
678
|
+
allowedGroups: z3.array(z3.string()).optional(),
|
|
679
|
+
excludedGroups: z3.array(z3.string()).optional(),
|
|
680
|
+
excludeComponentIds: z3.array(z3.string()).optional()
|
|
681
|
+
});
|
|
682
|
+
var primeUiComponentCandidatesInputSchema = z3.object({
|
|
683
|
+
pageSlug: primeUiPageSlugInputSchema,
|
|
684
|
+
pageType: primeUiPageGenerationTypeSchema,
|
|
685
|
+
blocks: z3.array(
|
|
686
|
+
z3.object({
|
|
687
|
+
componentId: z3.string()
|
|
688
|
+
})
|
|
689
|
+
),
|
|
690
|
+
operation: primeUiComponentCandidateOperationSchema,
|
|
691
|
+
count: z3.number().int().positive().optional(),
|
|
692
|
+
constraints: primeUiComponentCandidateConstraintsSchema.optional()
|
|
693
|
+
});
|
|
694
|
+
var primeUiComponentCandidateRequestEchoSchema = z3.object({
|
|
695
|
+
pageSlug: z3.string(),
|
|
696
|
+
pageType: z3.string(),
|
|
697
|
+
operation: primeUiComponentCandidateOperationSchema,
|
|
698
|
+
count: z3.number()
|
|
699
|
+
});
|
|
700
|
+
var requiredUnknownSchema = z3.custom((value) => value !== void 0);
|
|
701
|
+
var primeUiComponentCandidateLayoutObjectSchema = z3.object({
|
|
702
|
+
container: requiredUnknownSchema,
|
|
703
|
+
textAlignment: requiredUnknownSchema,
|
|
704
|
+
bottomWeight: requiredUnknownSchema,
|
|
705
|
+
entryWidth: requiredUnknownSchema,
|
|
706
|
+
exitWidth: requiredUnknownSchema,
|
|
707
|
+
orientation: requiredUnknownSchema,
|
|
708
|
+
structure: requiredUnknownSchema
|
|
709
|
+
});
|
|
710
|
+
var primeUiComponentCandidateLayoutSchema = z3.custom(
|
|
711
|
+
(value) => primeUiComponentCandidateLayoutObjectSchema.safeParse(value).success
|
|
712
|
+
);
|
|
713
|
+
var primeUiComponentCandidateObjectSchema = z3.object({
|
|
714
|
+
componentId: z3.string(),
|
|
715
|
+
name: z3.string(),
|
|
716
|
+
group: z3.string(),
|
|
717
|
+
familyId: z3.string(),
|
|
718
|
+
uxScore: z3.number(),
|
|
719
|
+
insertionScore: z3.number(),
|
|
720
|
+
followingScore: z3.number(),
|
|
721
|
+
layout: primeUiComponentCandidateLayoutSchema,
|
|
722
|
+
defaultProps: requiredUnknownSchema,
|
|
723
|
+
exportReady: z3.boolean(),
|
|
724
|
+
copyHints: z3.object({
|
|
725
|
+
deliveryToolchain: z3.array(z3.string())
|
|
726
|
+
}),
|
|
727
|
+
description: z3.string().nullable().optional(),
|
|
728
|
+
functionality: z3.string().nullable().optional(),
|
|
729
|
+
impression: z3.string().nullable().optional(),
|
|
730
|
+
visualStyle: z3.unknown().optional(),
|
|
731
|
+
compactSchema: z3.string().nullable().optional(),
|
|
732
|
+
jsonSchema: z3.record(z3.unknown()).nullable().optional()
|
|
733
|
+
});
|
|
734
|
+
var primeUiComponentCandidateSchema = z3.custom(
|
|
735
|
+
(value) => primeUiComponentCandidateObjectSchema.safeParse(value).success
|
|
736
|
+
);
|
|
737
|
+
var primeUiComponentCandidatesResponseSchema = z3.object({
|
|
738
|
+
request: primeUiComponentCandidateRequestEchoSchema,
|
|
739
|
+
candidates: z3.array(primeUiComponentCandidateSchema)
|
|
740
|
+
});
|
|
741
|
+
var primeUiComponentPropsValidateInputSchema = z3.object({
|
|
742
|
+
pageSlug: primeUiPageSlugInputSchema,
|
|
743
|
+
componentId: z3.string(),
|
|
744
|
+
props: z3.record(z3.unknown())
|
|
745
|
+
});
|
|
746
|
+
var primeUiComponentPropsValidationErrorSchema = z3.object({
|
|
747
|
+
path: z3.string(),
|
|
748
|
+
message: z3.string()
|
|
749
|
+
});
|
|
750
|
+
var primeUiComponentPropsRenderCheckSchema = z3.object({
|
|
751
|
+
attempted: z3.boolean(),
|
|
752
|
+
passed: z3.boolean(),
|
|
753
|
+
message: z3.string()
|
|
754
|
+
});
|
|
755
|
+
var primeUiComponentPropsValidateResponseSchema = z3.object({
|
|
756
|
+
valid: z3.boolean(),
|
|
757
|
+
normalizedProps: z3.record(z3.unknown()).nullable(),
|
|
758
|
+
errors: z3.array(primeUiComponentPropsValidationErrorSchema),
|
|
759
|
+
hints: z3.array(z3.string()),
|
|
760
|
+
renderCheck: primeUiComponentPropsRenderCheckSchema
|
|
761
|
+
});
|
|
642
762
|
var primeUiProjectApiWireframeStatusSchema = z3.enum(["pending", "generating", "ready", "error"]);
|
|
643
763
|
var primeUiProjectApiVariantSummarySchema = z3.object({
|
|
644
764
|
id: z3.string(),
|
|
@@ -1145,6 +1265,20 @@ var ApiProjectDataProvider = class {
|
|
|
1145
1265
|
primeUiProjectPageDetailsSchema
|
|
1146
1266
|
);
|
|
1147
1267
|
}
|
|
1268
|
+
async getComponentCandidates(input) {
|
|
1269
|
+
return this.requestJson(
|
|
1270
|
+
"component-planning/candidates",
|
|
1271
|
+
primeUiComponentCandidatesResponseSchema,
|
|
1272
|
+
this.buildJsonRequestInit(input)
|
|
1273
|
+
);
|
|
1274
|
+
}
|
|
1275
|
+
async validateComponentProps(input) {
|
|
1276
|
+
return this.requestJson(
|
|
1277
|
+
"component-planning/props/validate",
|
|
1278
|
+
primeUiComponentPropsValidateResponseSchema,
|
|
1279
|
+
this.buildJsonRequestInit(input)
|
|
1280
|
+
);
|
|
1281
|
+
}
|
|
1148
1282
|
async listExports() {
|
|
1149
1283
|
const response = await this.requestJson(
|
|
1150
1284
|
"project/exports",
|
|
@@ -1856,19 +1990,23 @@ async function runHealthCheck(options) {
|
|
|
1856
1990
|
apiKeyFromEnv: env.PRIMEUI_API_KEY
|
|
1857
1991
|
});
|
|
1858
1992
|
const configApiKeyState = resolvedProjectConfig ? "set" : configStatus === "missing" || configStatus === "unresolved" ? "missing" : "unknown";
|
|
1859
|
-
const
|
|
1993
|
+
const apiBaseUrlDetails = resolvePrimeUiApiBaseUrlDetails({
|
|
1994
|
+
projectConfig: resolvedProjectConfig?.projectConfig,
|
|
1995
|
+
baseUrlFromEnv: env.PRIMEUI_API_BASE_URL
|
|
1996
|
+
});
|
|
1997
|
+
const apiBaseUrlSource = apiBaseUrlDetails.source;
|
|
1860
1998
|
const defaultApiRoot = normalizePrimeUiApiRoot(DEFAULT_API_BASE_URL);
|
|
1861
1999
|
let apiRoot;
|
|
1862
2000
|
let projectInfoUrl;
|
|
1863
2001
|
let apiCheck;
|
|
1864
2002
|
try {
|
|
1865
|
-
apiRoot = normalizePrimeUiApiRoot(
|
|
2003
|
+
apiRoot = normalizePrimeUiApiRoot(apiBaseUrlDetails.baseUrl);
|
|
1866
2004
|
projectInfoUrl = buildPrimeUiApiUrl(apiRoot, "project");
|
|
1867
2005
|
} catch (error) {
|
|
1868
2006
|
apiCheck = {
|
|
1869
2007
|
status: "skipped",
|
|
1870
2008
|
apiBaseUrlSource,
|
|
1871
|
-
nonStandardBaseUrl: Boolean(
|
|
2009
|
+
nonStandardBaseUrl: Boolean(apiBaseUrlDetails.baseUrl?.trim()),
|
|
1872
2010
|
message: error instanceof Error ? error.message : String(error),
|
|
1873
2011
|
errorKind: "configuration"
|
|
1874
2012
|
};
|
|
@@ -1886,10 +2024,10 @@ async function runHealthCheck(options) {
|
|
|
1886
2024
|
} else {
|
|
1887
2025
|
const provider = options.createProvider?.({
|
|
1888
2026
|
apiKey: apiKeyDetails.apiKey,
|
|
1889
|
-
baseUrl:
|
|
2027
|
+
baseUrl: apiBaseUrlDetails.baseUrl
|
|
1890
2028
|
}) ?? new ApiProjectDataProvider({
|
|
1891
2029
|
apiKey: apiKeyDetails.apiKey,
|
|
1892
|
-
baseUrl:
|
|
2030
|
+
baseUrl: apiBaseUrlDetails.baseUrl
|
|
1893
2031
|
});
|
|
1894
2032
|
try {
|
|
1895
2033
|
await provider.getProjectInfo();
|
|
@@ -3741,6 +3879,15 @@ var PACKAGE_JSON_RELATIVE_PATH2 = "package.json";
|
|
|
3741
3879
|
var VIRTUAL_ROUTE_SEGMENT = "__primeui-component-export";
|
|
3742
3880
|
var COMPONENT_PAGES_PREFIX = "src/components/pages/";
|
|
3743
3881
|
var COMPONENT_UI_PREFIX = "src/components/ui/";
|
|
3882
|
+
var COMPONENT_SHARED_PREFIX = "src/components/shared/";
|
|
3883
|
+
var NATURAL_SUPPORT_PREFIXES = [
|
|
3884
|
+
COMPONENT_UI_PREFIX,
|
|
3885
|
+
"src/lib/",
|
|
3886
|
+
"src/types/",
|
|
3887
|
+
"src/contexts/"
|
|
3888
|
+
];
|
|
3889
|
+
var PUBLIC_PREFIX = "public/";
|
|
3890
|
+
var PUBLIC_ASSET_REFERENCE_RE = /["'`(]\/([^"'`()\s]+\.(?:avif|gif|ico|jpeg|jpg|json|mp4|otf|png|svg|ttf|txt|webm|webmanifest|webp|woff|woff2|xml))(?:\?[^"'`()\s]*)?["'`)]/giu;
|
|
3744
3891
|
function normalizeComponentId(componentId) {
|
|
3745
3892
|
const trimmed = componentId.trim();
|
|
3746
3893
|
if (!trimmed) {
|
|
@@ -3773,6 +3920,35 @@ function isVirtualRouteFile(relativePath) {
|
|
|
3773
3920
|
const segments = relativePath.split("/");
|
|
3774
3921
|
return segments[0] === "src" && segments[1] === "app" && segments.includes(VIRTUAL_ROUTE_SEGMENT);
|
|
3775
3922
|
}
|
|
3923
|
+
function getVirtualComponentRelativePath(relativePath, componentId) {
|
|
3924
|
+
const prefix = `${COMPONENT_PAGES_PREFIX}${VIRTUAL_ROUTE_SEGMENT}/${componentId}/`;
|
|
3925
|
+
if (!relativePath.startsWith(prefix)) {
|
|
3926
|
+
return null;
|
|
3927
|
+
}
|
|
3928
|
+
const componentRelativePath = relativePath.slice(prefix.length);
|
|
3929
|
+
return componentRelativePath || null;
|
|
3930
|
+
}
|
|
3931
|
+
function getComponentPageSourceArea(relativePath) {
|
|
3932
|
+
if (!relativePath.startsWith(COMPONENT_PAGES_PREFIX)) {
|
|
3933
|
+
return null;
|
|
3934
|
+
}
|
|
3935
|
+
const rest = relativePath.slice(COMPONENT_PAGES_PREFIX.length);
|
|
3936
|
+
const slashIndex = rest.indexOf("/");
|
|
3937
|
+
if (slashIndex <= 0) {
|
|
3938
|
+
return null;
|
|
3939
|
+
}
|
|
3940
|
+
const sourceArea = rest.slice(0, slashIndex);
|
|
3941
|
+
return sourceArea === VIRTUAL_ROUTE_SEGMENT ? null : sourceArea;
|
|
3942
|
+
}
|
|
3943
|
+
function getSourceAreaComponentRelativePath(relativePath, sourceAreas) {
|
|
3944
|
+
const sourceArea = getComponentPageSourceArea(relativePath);
|
|
3945
|
+
if (!sourceArea || !sourceAreas.has(sourceArea)) {
|
|
3946
|
+
return null;
|
|
3947
|
+
}
|
|
3948
|
+
const prefix = `${COMPONENT_PAGES_PREFIX}${sourceArea}/`;
|
|
3949
|
+
const componentRelativePath = relativePath.slice(prefix.length);
|
|
3950
|
+
return componentRelativePath || null;
|
|
3951
|
+
}
|
|
3776
3952
|
function isComponentEntryFile(relativePath, componentId) {
|
|
3777
3953
|
if (!relativePath.startsWith(COMPONENT_PAGES_PREFIX)) {
|
|
3778
3954
|
return false;
|
|
@@ -3788,7 +3964,155 @@ function isComponentEntryFile(relativePath, componentId) {
|
|
|
3788
3964
|
return basename === "index" && path13.basename(path13.dirname(relativePath)) === componentId;
|
|
3789
3965
|
}
|
|
3790
3966
|
function isManifestSupportFile(relativePath) {
|
|
3791
|
-
return
|
|
3967
|
+
return NATURAL_SUPPORT_PREFIXES.some(
|
|
3968
|
+
(prefix) => relativePath.startsWith(prefix)
|
|
3969
|
+
);
|
|
3970
|
+
}
|
|
3971
|
+
function isEnvFile(relativePath) {
|
|
3972
|
+
return relativePath === ".env" || relativePath.startsWith(".env.");
|
|
3973
|
+
}
|
|
3974
|
+
function isSearchRuntimeFile(relativePath) {
|
|
3975
|
+
return relativePath.startsWith("src/app/api/search/") || relativePath.startsWith("src/lib/search/") || relativePath.startsWith("src/lib/search-runtime/") || relativePath.startsWith("src/search/");
|
|
3976
|
+
}
|
|
3977
|
+
function isProjectLevelFile(relativePath) {
|
|
3978
|
+
return isEnvFile(relativePath) || isSearchRuntimeFile(relativePath) || relativePath.startsWith("scripts/") || relativePath.startsWith("src/app/") || relativePath.startsWith("src/components/header/") || relativePath.startsWith("src/components/footer/") || relativePath.startsWith("src/components/layout/");
|
|
3979
|
+
}
|
|
3980
|
+
function toComponentSharedTargetPath(componentRelativePath) {
|
|
3981
|
+
return `${COMPONENT_SHARED_PREFIX}${componentRelativePath}`;
|
|
3982
|
+
}
|
|
3983
|
+
function toImportPath(relativePath) {
|
|
3984
|
+
const withoutExtension = relativePath.replace(/\.[cm]?[jt]sx?$/u, "");
|
|
3985
|
+
const withoutIndex = withoutExtension.replace(/\/index$/u, "");
|
|
3986
|
+
return `@/${withoutIndex.replace(/^src\//u, "")}`;
|
|
3987
|
+
}
|
|
3988
|
+
function escapeRegExp(value) {
|
|
3989
|
+
return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
3990
|
+
}
|
|
3991
|
+
function sourceImportSpecifiers(relativePath) {
|
|
3992
|
+
const withAlias = toImportPath(relativePath);
|
|
3993
|
+
const specifiers = [withAlias];
|
|
3994
|
+
if (withAlias.endsWith("/index")) {
|
|
3995
|
+
specifiers.push(withAlias.replace(/\/index$/u, ""));
|
|
3996
|
+
}
|
|
3997
|
+
return [...new Set(specifiers)];
|
|
3998
|
+
}
|
|
3999
|
+
function rewriteComponentLocalImports(content, transfers) {
|
|
4000
|
+
let updated = content;
|
|
4001
|
+
for (const transfer of transfers) {
|
|
4002
|
+
const targetSpecifier = toImportPath(transfer.targetPath);
|
|
4003
|
+
for (const sourceSpecifier of sourceImportSpecifiers(transfer.sourcePath)) {
|
|
4004
|
+
updated = updated.replace(
|
|
4005
|
+
new RegExp(escapeRegExp(sourceSpecifier), "gu"),
|
|
4006
|
+
targetSpecifier
|
|
4007
|
+
);
|
|
4008
|
+
}
|
|
4009
|
+
}
|
|
4010
|
+
return updated;
|
|
4011
|
+
}
|
|
4012
|
+
function collectReferencedPublicAssetFiles(content) {
|
|
4013
|
+
const referencedFiles = /* @__PURE__ */ new Set();
|
|
4014
|
+
let match = null;
|
|
4015
|
+
PUBLIC_ASSET_REFERENCE_RE.lastIndex = 0;
|
|
4016
|
+
while ((match = PUBLIC_ASSET_REFERENCE_RE.exec(content)) !== null) {
|
|
4017
|
+
const referencedPath = match[1]?.trim();
|
|
4018
|
+
if (referencedPath) {
|
|
4019
|
+
referencedFiles.add(
|
|
4020
|
+
`${PUBLIC_PREFIX}${normalizeManifestFilePath(referencedPath)}`
|
|
4021
|
+
);
|
|
4022
|
+
}
|
|
4023
|
+
}
|
|
4024
|
+
return [...referencedFiles];
|
|
4025
|
+
}
|
|
4026
|
+
function findComponentSourceAreas(relativePaths) {
|
|
4027
|
+
const sourceAreas = /* @__PURE__ */ new Set();
|
|
4028
|
+
for (const relativePath of relativePaths) {
|
|
4029
|
+
const sourceArea = getComponentPageSourceArea(relativePath);
|
|
4030
|
+
if (sourceArea) {
|
|
4031
|
+
sourceAreas.add(sourceArea);
|
|
4032
|
+
}
|
|
4033
|
+
}
|
|
4034
|
+
return sourceAreas;
|
|
4035
|
+
}
|
|
4036
|
+
function getComponentLocalTargetPath(input) {
|
|
4037
|
+
const virtualRelativePath = getVirtualComponentRelativePath(
|
|
4038
|
+
input.relativePath,
|
|
4039
|
+
input.componentId
|
|
4040
|
+
);
|
|
4041
|
+
if (virtualRelativePath) {
|
|
4042
|
+
return toComponentSharedTargetPath(virtualRelativePath);
|
|
4043
|
+
}
|
|
4044
|
+
const sourceAreaRelativePath = getSourceAreaComponentRelativePath(
|
|
4045
|
+
input.relativePath,
|
|
4046
|
+
input.sourceAreas
|
|
4047
|
+
);
|
|
4048
|
+
if (sourceAreaRelativePath) {
|
|
4049
|
+
return toComponentSharedTargetPath(sourceAreaRelativePath);
|
|
4050
|
+
}
|
|
4051
|
+
return null;
|
|
4052
|
+
}
|
|
4053
|
+
function getTransferTargetPath(input) {
|
|
4054
|
+
if (input.relativePath === PACKAGE_JSON_RELATIVE_PATH2 || isVirtualRouteFile(input.relativePath) || isProjectLevelFile(input.relativePath)) {
|
|
4055
|
+
return null;
|
|
4056
|
+
}
|
|
4057
|
+
const componentLocalTargetPath = getComponentLocalTargetPath(input);
|
|
4058
|
+
if (componentLocalTargetPath) {
|
|
4059
|
+
return componentLocalTargetPath;
|
|
4060
|
+
}
|
|
4061
|
+
if (isManifestSupportFile(input.relativePath)) {
|
|
4062
|
+
return input.relativePath;
|
|
4063
|
+
}
|
|
4064
|
+
if (input.relativePath.startsWith(PUBLIC_PREFIX) && input.referencedPublicFiles.has(input.relativePath)) {
|
|
4065
|
+
return input.relativePath;
|
|
4066
|
+
}
|
|
4067
|
+
return null;
|
|
4068
|
+
}
|
|
4069
|
+
async function collectReferencedPublicFiles(input) {
|
|
4070
|
+
const referencedPublicFiles = /* @__PURE__ */ new Set();
|
|
4071
|
+
for (const relativePath of input.graphInternalFiles) {
|
|
4072
|
+
if (!input.manifestFileSet.has(relativePath)) {
|
|
4073
|
+
continue;
|
|
4074
|
+
}
|
|
4075
|
+
const sourcePath = path13.join(input.exportPath, relativePath);
|
|
4076
|
+
let content = "";
|
|
4077
|
+
try {
|
|
4078
|
+
content = await readFile7(sourcePath, "utf-8");
|
|
4079
|
+
} catch {
|
|
4080
|
+
continue;
|
|
4081
|
+
}
|
|
4082
|
+
for (const referencedFile of collectReferencedPublicAssetFiles(content)) {
|
|
4083
|
+
if (input.manifestFileSet.has(referencedFile)) {
|
|
4084
|
+
referencedPublicFiles.add(referencedFile);
|
|
4085
|
+
}
|
|
4086
|
+
}
|
|
4087
|
+
}
|
|
4088
|
+
return referencedPublicFiles;
|
|
4089
|
+
}
|
|
4090
|
+
function buildFileTransfers(input) {
|
|
4091
|
+
const sourceAreas = findComponentSourceAreas([...input.graphInternalFiles]);
|
|
4092
|
+
const transfers = [];
|
|
4093
|
+
const usedTargetPaths = /* @__PURE__ */ new Set();
|
|
4094
|
+
for (const relativePath of input.files) {
|
|
4095
|
+
const isGraphFile = input.graphInternalFiles.has(relativePath);
|
|
4096
|
+
const isReferencedPublicFile = input.referencedPublicFiles.has(relativePath);
|
|
4097
|
+
if (!isGraphFile && !isReferencedPublicFile) {
|
|
4098
|
+
continue;
|
|
4099
|
+
}
|
|
4100
|
+
const targetPath = getTransferTargetPath({
|
|
4101
|
+
relativePath,
|
|
4102
|
+
componentId: input.componentId,
|
|
4103
|
+
sourceAreas,
|
|
4104
|
+
referencedPublicFiles: input.referencedPublicFiles
|
|
4105
|
+
});
|
|
4106
|
+
if (!targetPath || usedTargetPaths.has(targetPath)) {
|
|
4107
|
+
continue;
|
|
4108
|
+
}
|
|
4109
|
+
usedTargetPaths.add(targetPath);
|
|
4110
|
+
transfers.push({
|
|
4111
|
+
sourcePath: relativePath,
|
|
4112
|
+
targetPath
|
|
4113
|
+
});
|
|
4114
|
+
}
|
|
4115
|
+
return transfers.sort((a, b) => a.targetPath.localeCompare(b.targetPath));
|
|
3792
4116
|
}
|
|
3793
4117
|
function toSkippedFile(targetPath, reason) {
|
|
3794
4118
|
return {
|
|
@@ -3828,7 +4152,7 @@ function splitManifestFiles(input) {
|
|
|
3828
4152
|
};
|
|
3829
4153
|
}
|
|
3830
4154
|
async function createConflictReportEntry2(input) {
|
|
3831
|
-
const sourceBuffer = await readFile7(input.sourceFilePath);
|
|
4155
|
+
const sourceBuffer = input.sourceBuffer ?? await readFile7(input.sourceFilePath);
|
|
3832
4156
|
let targetBuffer = null;
|
|
3833
4157
|
try {
|
|
3834
4158
|
targetBuffer = await readFile7(input.targetFilePath);
|
|
@@ -3896,7 +4220,7 @@ function buildMessage(input) {
|
|
|
3896
4220
|
);
|
|
3897
4221
|
}
|
|
3898
4222
|
parts.push(
|
|
3899
|
-
|
|
4223
|
+
`The virtual component export page was skipped; manually import ${input.componentImportPath} into a real target page.`
|
|
3900
4224
|
);
|
|
3901
4225
|
return parts.join(" ");
|
|
3902
4226
|
}
|
|
@@ -3963,23 +4287,39 @@ async function copyRegistryComponentFromExport(input) {
|
|
|
3963
4287
|
(filePath) => toProjectRelative(exportPath, filePath)
|
|
3964
4288
|
)
|
|
3965
4289
|
);
|
|
3966
|
-
const
|
|
3967
|
-
|
|
4290
|
+
const referencedPublicFiles = await collectReferencedPublicFiles({
|
|
4291
|
+
exportPath,
|
|
4292
|
+
graphInternalFiles,
|
|
4293
|
+
manifestFileSet
|
|
4294
|
+
});
|
|
4295
|
+
const fileTransfers = buildFileTransfers({
|
|
4296
|
+
files: initialSelection.manifestFiles,
|
|
4297
|
+
componentId: normalizedComponentId,
|
|
4298
|
+
graphInternalFiles,
|
|
4299
|
+
referencedPublicFiles
|
|
4300
|
+
});
|
|
4301
|
+
const copyableSourceFiles = fileTransfers.map(
|
|
4302
|
+
(transfer) => transfer.sourcePath
|
|
4303
|
+
);
|
|
4304
|
+
const copyableFiles = fileTransfers.map((transfer) => transfer.targetPath);
|
|
4305
|
+
const transferBySourcePath = new Map(
|
|
4306
|
+
fileTransfers.map((transfer) => [transfer.sourcePath, transfer])
|
|
4307
|
+
);
|
|
4308
|
+
const componentEntryTransfer = fileTransfers.find(
|
|
4309
|
+
(transfer) => initialSelection.componentEntryFiles.includes(transfer.sourcePath)
|
|
4310
|
+
);
|
|
4311
|
+
const componentImportPath = toImportPath(
|
|
4312
|
+
componentEntryTransfer?.targetPath ?? `${COMPONENT_SHARED_PREFIX}${normalizedComponentId}.tsx`
|
|
3968
4313
|
);
|
|
3969
|
-
const copyableFiles = initialSelection.manifestFiles.filter(
|
|
3970
|
-
(relativePath) => graphInternalFiles.has(relativePath) || isManifestSupportFile(relativePath) || exportableFileSet.has(relativePath)
|
|
3971
|
-
).filter(
|
|
3972
|
-
(relativePath) => relativePath !== PACKAGE_JSON_RELATIVE_PATH2 && !isVirtualRouteFile(relativePath)
|
|
3973
|
-
).sort((a, b) => a.localeCompare(b));
|
|
3974
4314
|
const { manifestFiles, skippedFiles } = splitManifestFiles({
|
|
3975
4315
|
files: initialSelection.manifestFiles,
|
|
3976
4316
|
componentId: normalizedComponentId,
|
|
3977
|
-
copyableFiles
|
|
4317
|
+
copyableFiles: copyableSourceFiles
|
|
3978
4318
|
});
|
|
3979
4319
|
const candidateFiles = await resolveManifestCandidateFiles({
|
|
3980
4320
|
exportPath,
|
|
3981
4321
|
manifestOwnerLabel: `registry component "${normalizedComponentId}"`,
|
|
3982
|
-
files:
|
|
4322
|
+
files: copyableSourceFiles,
|
|
3983
4323
|
requireExisting: false
|
|
3984
4324
|
});
|
|
3985
4325
|
for (const sourceFilePath of candidateFiles) {
|
|
@@ -3989,9 +4329,21 @@ async function copyRegistryComponentFromExport(input) {
|
|
|
3989
4329
|
missingManifestFiles.add(relativeToExport);
|
|
3990
4330
|
continue;
|
|
3991
4331
|
}
|
|
3992
|
-
const
|
|
4332
|
+
const transfer = transferBySourcePath.get(relativeToExport);
|
|
4333
|
+
if (!transfer) {
|
|
4334
|
+
continue;
|
|
4335
|
+
}
|
|
4336
|
+
const targetRelativePath = transfer.targetPath;
|
|
4337
|
+
const targetFilePath = path13.join(input.projectRoot, targetRelativePath);
|
|
3993
4338
|
ensureSafeTargetPath(input.projectRoot, targetFilePath);
|
|
3994
4339
|
const sourceBuffer = await readFile7(sourceFilePath);
|
|
4340
|
+
const rewrittenSourceBuffer = isBinaryBuffer(sourceBuffer) ? sourceBuffer : Buffer.from(
|
|
4341
|
+
rewriteComponentLocalImports(
|
|
4342
|
+
sourceBuffer.toString("utf-8"),
|
|
4343
|
+
fileTransfers
|
|
4344
|
+
),
|
|
4345
|
+
"utf-8"
|
|
4346
|
+
);
|
|
3995
4347
|
let targetBuffer = null;
|
|
3996
4348
|
try {
|
|
3997
4349
|
targetBuffer = await readFile7(targetFilePath);
|
|
@@ -4000,19 +4352,20 @@ async function copyRegistryComponentFromExport(input) {
|
|
|
4000
4352
|
}
|
|
4001
4353
|
if (!targetBuffer) {
|
|
4002
4354
|
await ensureDir(path13.dirname(targetFilePath));
|
|
4003
|
-
await writeFile6(targetFilePath,
|
|
4004
|
-
newFiles.push(
|
|
4355
|
+
await writeFile6(targetFilePath, rewrittenSourceBuffer);
|
|
4356
|
+
newFiles.push(targetRelativePath);
|
|
4005
4357
|
continue;
|
|
4006
4358
|
}
|
|
4007
|
-
if (
|
|
4008
|
-
identicalFiles.push(
|
|
4359
|
+
if (rewrittenSourceBuffer.equals(targetBuffer)) {
|
|
4360
|
+
identicalFiles.push(targetRelativePath);
|
|
4009
4361
|
continue;
|
|
4010
4362
|
}
|
|
4011
4363
|
const entry = await createConflictReportEntry2({
|
|
4012
4364
|
sourceFilePath,
|
|
4013
4365
|
targetFilePath,
|
|
4014
4366
|
exportPath,
|
|
4015
|
-
projectRoot: input.projectRoot
|
|
4367
|
+
projectRoot: input.projectRoot,
|
|
4368
|
+
sourceBuffer: rewrittenSourceBuffer
|
|
4016
4369
|
});
|
|
4017
4370
|
if (entry) {
|
|
4018
4371
|
conflictReportEntries.push(entry);
|
|
@@ -4053,6 +4406,7 @@ async function copyRegistryComponentFromExport(input) {
|
|
|
4053
4406
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4054
4407
|
exportId,
|
|
4055
4408
|
componentId: normalizedComponentId,
|
|
4409
|
+
componentImportPath,
|
|
4056
4410
|
manifestFiles,
|
|
4057
4411
|
copyableFiles,
|
|
4058
4412
|
skippedFiles,
|
|
@@ -4074,6 +4428,7 @@ async function copyRegistryComponentFromExport(input) {
|
|
|
4074
4428
|
status,
|
|
4075
4429
|
message: buildMessage({
|
|
4076
4430
|
componentId: normalizedComponentId,
|
|
4431
|
+
componentImportPath,
|
|
4077
4432
|
status,
|
|
4078
4433
|
reportPath,
|
|
4079
4434
|
newFiles: sortedNewFiles,
|
|
@@ -4089,6 +4444,7 @@ async function copyRegistryComponentFromExport(input) {
|
|
|
4089
4444
|
exportPath,
|
|
4090
4445
|
manifestPath,
|
|
4091
4446
|
component: manifest.component,
|
|
4447
|
+
componentImportPath,
|
|
4092
4448
|
manifestFiles,
|
|
4093
4449
|
copyableFiles,
|
|
4094
4450
|
newFiles: sortedNewFiles,
|
|
@@ -4111,7 +4467,7 @@ async function copyRegistryComponentFromExport(input) {
|
|
|
4111
4467
|
},
|
|
4112
4468
|
guidance: {
|
|
4113
4469
|
artifacts: guidanceArtifacts,
|
|
4114
|
-
requiredActions:
|
|
4470
|
+
requiredActions: `Do not install the skipped virtual component export page as a route. Manually import ${componentImportPath} into a real target page, install newly added dependencies, and resolve any reported conflicts or dependency version mismatches before treating the registry component transfer as complete.`
|
|
4115
4471
|
}
|
|
4116
4472
|
};
|
|
4117
4473
|
}
|
|
@@ -4294,6 +4650,12 @@ var ProjectSyncService = class {
|
|
|
4294
4650
|
notes: guidanceNotes
|
|
4295
4651
|
};
|
|
4296
4652
|
}
|
|
4653
|
+
async getComponentCandidates(input, _context) {
|
|
4654
|
+
return this.provider.getComponentCandidates(input);
|
|
4655
|
+
}
|
|
4656
|
+
async validateComponentProps(input, _context) {
|
|
4657
|
+
return this.provider.validateComponentProps(input);
|
|
4658
|
+
}
|
|
4297
4659
|
async listExports(_context) {
|
|
4298
4660
|
await this.ensureTempLayout();
|
|
4299
4661
|
return this.provider.listExports();
|
|
@@ -4552,10 +4914,14 @@ var LazyProjectSyncSource = class {
|
|
|
4552
4914
|
projectConfig: resolvedProjectConfig.projectConfig,
|
|
4553
4915
|
apiKeyFromEnv: this.env.PRIMEUI_API_KEY
|
|
4554
4916
|
});
|
|
4917
|
+
const baseUrl = resolvePrimeUiApiBaseUrl({
|
|
4918
|
+
projectConfig: resolvedProjectConfig.projectConfig,
|
|
4919
|
+
baseUrlFromEnv: this.env.PRIMEUI_API_BASE_URL
|
|
4920
|
+
});
|
|
4555
4921
|
this.stickyProjectRoot = projectRoot;
|
|
4556
4922
|
const provider = this.createProvider({
|
|
4557
4923
|
apiKey,
|
|
4558
|
-
baseUrl
|
|
4924
|
+
baseUrl
|
|
4559
4925
|
});
|
|
4560
4926
|
return new ProjectSyncService({
|
|
4561
4927
|
projectRoot,
|
|
@@ -4738,6 +5104,24 @@ var LazyProjectSyncSource = class {
|
|
|
4738
5104
|
(service) => service.syncSearchEnvironment(environmentSlug, context)
|
|
4739
5105
|
);
|
|
4740
5106
|
}
|
|
5107
|
+
async getComponentCandidates(input, context) {
|
|
5108
|
+
return this.withService(
|
|
5109
|
+
context,
|
|
5110
|
+
(service) => service.getComponentCandidates(input, context),
|
|
5111
|
+
{
|
|
5112
|
+
requireTargetProjectRoot: false
|
|
5113
|
+
}
|
|
5114
|
+
);
|
|
5115
|
+
}
|
|
5116
|
+
async validateComponentProps(input, context) {
|
|
5117
|
+
return this.withService(
|
|
5118
|
+
context,
|
|
5119
|
+
(service) => service.validateComponentProps(input, context),
|
|
5120
|
+
{
|
|
5121
|
+
requireTargetProjectRoot: false
|
|
5122
|
+
}
|
|
5123
|
+
);
|
|
5124
|
+
}
|
|
4741
5125
|
async listExports(context) {
|
|
4742
5126
|
return this.withService(context, (service) => service.listExports(context));
|
|
4743
5127
|
}
|
|
@@ -5032,7 +5416,8 @@ ${WORKFLOW_SUMMARY}
|
|
|
5032
5416
|
|
|
5033
5417
|
ADDITIONAL CAPABILITIES:
|
|
5034
5418
|
- PrimeUI MCP also exposes atomic external API tools for project description, project pages, page variants, active-variant selection, and issue reports.
|
|
5035
|
-
-
|
|
5419
|
+
- PrimeUI MCP also exposes component planning tools such as component_candidates_get and component_props_validate for exported-project page building.
|
|
5420
|
+
- These additional tools are OPTIONAL capabilities for extended scenarios.
|
|
5036
5421
|
- They are NOT part of the primary import/export workflow above.
|
|
5037
5422
|
- 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.
|
|
5038
5423
|
|
|
@@ -5594,10 +5979,12 @@ WHEN TO USE:
|
|
|
5594
5979
|
BEHAVIOR:
|
|
5595
5980
|
- Reads the component sidecar manifest saved by create_component_export.
|
|
5596
5981
|
- Validates that manifest.component.componentId matches input.componentId.
|
|
5597
|
-
- Copies
|
|
5982
|
+
- Copies only the selected registry component import graph, narrowly referenced public assets, and safe support files from the component sidecar manifest/export.
|
|
5983
|
+
- Remaps component-local files into src/components/shared/** and returns componentImportPath for manual insertion.
|
|
5598
5984
|
- Skips virtual route files that include __primeui-component-export, because those are reference/insertion hints and must not be installed as normal app routes.
|
|
5985
|
+
- Skips app/search/layout/header/footer/env/project-shell files instead of copying whole exportable buckets.
|
|
5599
5986
|
- Never copies package.json directly. package.json is used only to add missing dependency entries and report dependency version conflicts.
|
|
5600
|
-
-
|
|
5987
|
+
- Keeps safe support files on their natural target paths, such as src/components/ui/**, src/lib/**, src/types/**, and src/contexts/**.
|
|
5601
5988
|
- Never overwrites existing conflicting files.
|
|
5602
5989
|
- Writes full conflict details to .primeui/temp/exports/[exportId].copy-registry-component-report-[copyId].json.
|
|
5603
5990
|
- Reports copied files, identical files, conflicts, skipped files, dependency additions, dependency version conflicts, missing manifest files, and manual insertion guidance.
|
|
@@ -5628,11 +6015,14 @@ ${WORKFLOW_SUMMARY}`,
|
|
|
5628
6015
|
component: componentExportComponentSchema.describe(
|
|
5629
6016
|
"Component metadata from the validated component sidecar manifest."
|
|
5630
6017
|
),
|
|
6018
|
+
componentImportPath: z4.string().describe(
|
|
6019
|
+
"Canonical import path for the copied registry component entrypoint, for example @/components/shared/hero--pricing."
|
|
6020
|
+
),
|
|
5631
6021
|
manifestFiles: z4.array(z4.string()).describe(
|
|
5632
|
-
"Normalized
|
|
6022
|
+
"Normalized component sidecar manifest files considered by the copy service."
|
|
5633
6023
|
),
|
|
5634
6024
|
copyableFiles: z4.array(z4.string()).describe(
|
|
5635
|
-
"
|
|
6025
|
+
"Relative target paths considered for copying after component remapping and safety filtering."
|
|
5636
6026
|
),
|
|
5637
6027
|
newFiles: z4.array(z4.string()).describe("Relative target paths for new files copied."),
|
|
5638
6028
|
identicalFiles: z4.array(z4.string()).describe("Relative target paths for existing byte-identical files."),
|
|
@@ -5821,6 +6211,122 @@ var pageGenerationTypeSchema = z4.enum([
|
|
|
5821
6211
|
]).describe(
|
|
5822
6212
|
"Supported PrimeUI page type. Must match the external API page type enum."
|
|
5823
6213
|
);
|
|
6214
|
+
var componentCandidateOperationSchema = z4.discriminatedUnion("type", [
|
|
6215
|
+
z4.object({
|
|
6216
|
+
type: z4.literal("append")
|
|
6217
|
+
}),
|
|
6218
|
+
z4.object({
|
|
6219
|
+
type: z4.literal("insert"),
|
|
6220
|
+
index: z4.number().int().describe("Zero-based insertion index in the ordered blocks list.")
|
|
6221
|
+
}),
|
|
6222
|
+
z4.object({
|
|
6223
|
+
type: z4.literal("replace"),
|
|
6224
|
+
index: z4.number().int().describe("Zero-based index of the block being replaced.")
|
|
6225
|
+
})
|
|
6226
|
+
]);
|
|
6227
|
+
var componentCandidatesGetInputSchema = z4.object({
|
|
6228
|
+
projectRoot: projectRootInputSchema,
|
|
6229
|
+
pageSlug: z4.string().refine((value) => value.trim().length > 0, {
|
|
6230
|
+
message: "pageSlug must be a non-empty string"
|
|
6231
|
+
}).describe(
|
|
6232
|
+
"Stable PrimeUI page slug used for candidate scoring and automatic diagnostics, for example '/pricing'."
|
|
6233
|
+
),
|
|
6234
|
+
pageType: pageGenerationTypeSchema,
|
|
6235
|
+
blocks: z4.array(
|
|
6236
|
+
z4.object({
|
|
6237
|
+
componentId: z4.string().describe("PrimeUI component id already present in page order.")
|
|
6238
|
+
})
|
|
6239
|
+
).describe(
|
|
6240
|
+
"Current ordered page composition before applying the requested operation."
|
|
6241
|
+
),
|
|
6242
|
+
operation: componentCandidateOperationSchema.optional().default({ type: "append" }).describe(
|
|
6243
|
+
"Candidate placement operation. Omit for the normal append flow."
|
|
6244
|
+
),
|
|
6245
|
+
count: z4.number().int().positive().optional().describe("Optional maximum candidate count. Studio defaults to 8."),
|
|
6246
|
+
constraints: z4.object({
|
|
6247
|
+
spreadDegree: z4.enum(["any-group", "same-group", "same-family"]).optional().describe("Optional UX scoring spread override."),
|
|
6248
|
+
allowedGroups: z4.array(z4.string()).optional().describe("Optional allow-list of candidate groups."),
|
|
6249
|
+
excludedGroups: z4.array(z4.string()).optional().describe("Optional deny-list of candidate groups."),
|
|
6250
|
+
excludeComponentIds: z4.array(z4.string()).optional().describe("Optional component ids to remove from the candidate pool.")
|
|
6251
|
+
}).optional().describe("Optional advanced candidate pool and spread constraints.")
|
|
6252
|
+
});
|
|
6253
|
+
var componentCandidatesGetValidationSchema = componentCandidatesGetInputSchema;
|
|
6254
|
+
var componentPropsValidateInputSchema = z4.object({
|
|
6255
|
+
projectRoot: projectRootInputSchema,
|
|
6256
|
+
pageSlug: z4.string().refine((value) => value.trim().length > 0, {
|
|
6257
|
+
message: "pageSlug must be a non-empty string"
|
|
6258
|
+
}).describe(
|
|
6259
|
+
"Stable PrimeUI page slug used for validation diagnostics, for example '/pricing'. Use the same pageSlug as candidate retrieval."
|
|
6260
|
+
),
|
|
6261
|
+
componentId: z4.string().describe("PrimeUI component registry identifier selected by the agent."),
|
|
6262
|
+
props: z4.record(z4.unknown()).describe(
|
|
6263
|
+
"Agent-authored props payload to validate against PrimeUI's registry schema."
|
|
6264
|
+
)
|
|
6265
|
+
});
|
|
6266
|
+
var componentPropsValidateValidationSchema = componentPropsValidateInputSchema;
|
|
6267
|
+
var componentCandidateLayoutSchema = z4.object({
|
|
6268
|
+
container: z4.unknown().describe("Layout container metadata."),
|
|
6269
|
+
textAlignment: z4.unknown().describe("Text alignment metadata."),
|
|
6270
|
+
bottomWeight: z4.unknown().describe("Bottom visual weight metadata."),
|
|
6271
|
+
entryWidth: z4.unknown().describe("Incoming width rhythm metadata."),
|
|
6272
|
+
exitWidth: z4.unknown().describe("Outgoing width rhythm metadata."),
|
|
6273
|
+
orientation: z4.unknown().describe("Optional orientation metadata."),
|
|
6274
|
+
structure: z4.unknown().describe("Optional structure metadata.")
|
|
6275
|
+
});
|
|
6276
|
+
var componentCandidateSchema = z4.object({
|
|
6277
|
+
componentId: z4.string().describe("PrimeUI component registry identifier to choose or export."),
|
|
6278
|
+
name: z4.string().describe("Human-readable component name."),
|
|
6279
|
+
group: z4.string().describe("Component group used by candidate scoring."),
|
|
6280
|
+
familyId: z4.string().describe("Component family identifier from catalog."),
|
|
6281
|
+
uxScore: z4.number().describe("Total UX score used for ranking."),
|
|
6282
|
+
insertionScore: z4.number().describe("Score for inserting this candidate at the requested position."),
|
|
6283
|
+
followingScore: z4.number().describe("Neighbor compatibility score with the following block."),
|
|
6284
|
+
layout: componentCandidateLayoutSchema.describe(
|
|
6285
|
+
"Layout metadata useful for choosing visual rhythm."
|
|
6286
|
+
),
|
|
6287
|
+
defaultProps: z4.unknown().describe("Registry default props, when available from PrimeUI."),
|
|
6288
|
+
exportReady: z4.boolean().describe("True when the component is expected to be exportable."),
|
|
6289
|
+
copyHints: z4.object({
|
|
6290
|
+
deliveryToolchain: z4.array(z4.string()).describe(
|
|
6291
|
+
"Recommended tool sequence for delivering this registry component locally."
|
|
6292
|
+
)
|
|
6293
|
+
}).describe("Machine-readable delivery hints for the selected candidate."),
|
|
6294
|
+
description: z4.string().nullable().optional(),
|
|
6295
|
+
functionality: z4.string().nullable().optional(),
|
|
6296
|
+
impression: z4.string().nullable().optional(),
|
|
6297
|
+
visualStyle: z4.unknown().optional(),
|
|
6298
|
+
compactSchema: z4.string().nullable().optional(),
|
|
6299
|
+
jsonSchema: z4.record(z4.unknown()).nullable().optional()
|
|
6300
|
+
});
|
|
6301
|
+
var componentCandidatesGetOutputSchema = z4.object({
|
|
6302
|
+
request: z4.object({
|
|
6303
|
+
pageSlug: z4.string(),
|
|
6304
|
+
pageType: z4.string(),
|
|
6305
|
+
operation: componentCandidateOperationSchema,
|
|
6306
|
+
count: z4.number()
|
|
6307
|
+
}).describe("Normalized request echo returned by PrimeUI."),
|
|
6308
|
+
candidates: z4.array(componentCandidateSchema).describe("Ranked rich candidate shortlist returned by PrimeUI.")
|
|
6309
|
+
});
|
|
6310
|
+
var componentPropsValidationErrorSchema = z4.object({
|
|
6311
|
+
path: z4.string().describe("JSON path or root path for the invalid props location."),
|
|
6312
|
+
message: z4.string().describe("Actionable validation message returned by PrimeUI.")
|
|
6313
|
+
});
|
|
6314
|
+
var componentPropsRenderCheckSchema = z4.object({
|
|
6315
|
+
attempted: z4.boolean().describe("True when PrimeUI attempted a render smoke check."),
|
|
6316
|
+
passed: z4.boolean().describe("True when the render smoke check passed."),
|
|
6317
|
+
message: z4.string().describe("Human-readable render check status or skip reason.")
|
|
6318
|
+
});
|
|
6319
|
+
var componentPropsValidateOutputSchema = z4.object({
|
|
6320
|
+
valid: z4.boolean().describe("True when props passed schema validation."),
|
|
6321
|
+
normalizedProps: z4.record(z4.unknown()).nullable().describe(
|
|
6322
|
+
"Props normalized by PrimeUI when valid; null when validation failed."
|
|
6323
|
+
),
|
|
6324
|
+
errors: z4.array(componentPropsValidationErrorSchema).describe("Structured validation errors for invalid props."),
|
|
6325
|
+
hints: z4.array(z4.string()).describe("Agent-facing guidance for correcting invalid props."),
|
|
6326
|
+
renderCheck: componentPropsRenderCheckSchema.describe(
|
|
6327
|
+
"Optional render-smoke status returned by PrimeUI."
|
|
6328
|
+
)
|
|
6329
|
+
});
|
|
5824
6330
|
var projectApiPageResourceSchema = z4.object({
|
|
5825
6331
|
id: z4.string().describe("Stable PrimeUI page identifier."),
|
|
5826
6332
|
title: z4.string().describe("Human-readable page title."),
|
|
@@ -6254,6 +6760,51 @@ WHEN TO USE:
|
|
|
6254
6760
|
openWorldHint: true
|
|
6255
6761
|
}
|
|
6256
6762
|
};
|
|
6763
|
+
var toolComponentCandidatesGet = {
|
|
6764
|
+
title: "PrimeUI Component Candidates Get",
|
|
6765
|
+
description: `External planning helper. Returns a ranked rich candidate shortlist for adding, inserting, or replacing one PrimeUI component in an exported-project page composition.
|
|
6766
|
+
|
|
6767
|
+
WHEN TO USE:
|
|
6768
|
+
- Use this when building or editing a local exported-project page and you need PrimeUI scoring guidance for which componentId to choose next.
|
|
6769
|
+
- The normal flow is append: pass the current ordered blocks and omit operation, which defaults to { "type": "append" }.
|
|
6770
|
+
- Use insert or replace only when the caller is intentionally editing a specific position in the ordered blocks list.
|
|
6771
|
+
- Use the returned copyHints.deliveryToolchain when the chosen candidate must be delivered locally: create_component_export, download_component_export, then copy_registry_component.
|
|
6772
|
+
|
|
6773
|
+
AFTER CALLING:
|
|
6774
|
+
- Choose from candidates using uxScore, insertionScore, followingScore, group/family/layout rhythm, descriptions, defaults, and schemas.
|
|
6775
|
+
- Do not mutate Prime page state from this tool result. This is planning guidance only.
|
|
6776
|
+
- Keep the same pageSlug across later planning and validation calls so PrimeUI diagnostics stay correlated.`,
|
|
6777
|
+
inputSchema: componentCandidatesGetInputSchema,
|
|
6778
|
+
outputSchema: componentCandidatesGetOutputSchema,
|
|
6779
|
+
annotations: {
|
|
6780
|
+
readOnlyHint: true,
|
|
6781
|
+
destructiveHint: false,
|
|
6782
|
+
idempotentHint: true,
|
|
6783
|
+
openWorldHint: true
|
|
6784
|
+
}
|
|
6785
|
+
};
|
|
6786
|
+
var toolComponentPropsValidate = {
|
|
6787
|
+
title: "PrimeUI Component Props Validate",
|
|
6788
|
+
description: `External planning helper. Validates agent-authored props for one selected PrimeUI component before editing local exported-project files.
|
|
6789
|
+
|
|
6790
|
+
WHEN TO USE:
|
|
6791
|
+
- Use this after choosing a component candidate and drafting props from the user's brief, candidate metadata, defaultProps, compactSchema, or jsonSchema.
|
|
6792
|
+
- Keep pageSlug stable across candidate retrieval and validation so PrimeUI diagnostics stay correlated.
|
|
6793
|
+
- Treat valid: false as actionable feedback, not a transport failure. Fix the props from errors and hints, then call this tool again.
|
|
6794
|
+
|
|
6795
|
+
AFTER CALLING:
|
|
6796
|
+
- If valid is true, use normalizedProps for local page edits.
|
|
6797
|
+
- If valid is false, correct props using errors[].path, errors[].message, and hints before editing local files.
|
|
6798
|
+
- Do not mutate Prime page state from this tool result. This is validation guidance only.`,
|
|
6799
|
+
inputSchema: componentPropsValidateInputSchema,
|
|
6800
|
+
outputSchema: componentPropsValidateOutputSchema,
|
|
6801
|
+
annotations: {
|
|
6802
|
+
readOnlyHint: true,
|
|
6803
|
+
destructiveHint: false,
|
|
6804
|
+
idempotentHint: true,
|
|
6805
|
+
openWorldHint: true
|
|
6806
|
+
}
|
|
6807
|
+
};
|
|
6257
6808
|
var toolProjectIssueReportSubmit = {
|
|
6258
6809
|
title: "PrimeUI Project Issue Report Submit",
|
|
6259
6810
|
description: `Atomic external API helper. Submits an issue report for the scoped PrimeUI project.
|
|
@@ -6664,6 +7215,32 @@ function createPrimeUiMcpServer(source) {
|
|
|
6664
7215
|
}
|
|
6665
7216
|
}
|
|
6666
7217
|
);
|
|
7218
|
+
server.registerTool(
|
|
7219
|
+
"component_candidates_get",
|
|
7220
|
+
toolComponentCandidatesGet,
|
|
7221
|
+
async (args) => {
|
|
7222
|
+
try {
|
|
7223
|
+
const { projectRoot, ...input } = componentCandidatesGetValidationSchema.parse(args);
|
|
7224
|
+
const result = await source.getComponentCandidates(input, { projectRoot });
|
|
7225
|
+
return okResult("component_candidates_get", result);
|
|
7226
|
+
} catch (error) {
|
|
7227
|
+
return errorResult(error);
|
|
7228
|
+
}
|
|
7229
|
+
}
|
|
7230
|
+
);
|
|
7231
|
+
server.registerTool(
|
|
7232
|
+
"component_props_validate",
|
|
7233
|
+
toolComponentPropsValidate,
|
|
7234
|
+
async (args) => {
|
|
7235
|
+
try {
|
|
7236
|
+
const { projectRoot, ...input } = componentPropsValidateValidationSchema.parse(args);
|
|
7237
|
+
const result = await source.validateComponentProps(input, { projectRoot });
|
|
7238
|
+
return okResult("component_props_validate", result);
|
|
7239
|
+
} catch (error) {
|
|
7240
|
+
return errorResult(error);
|
|
7241
|
+
}
|
|
7242
|
+
}
|
|
7243
|
+
);
|
|
6667
7244
|
server.registerTool(
|
|
6668
7245
|
"list_exports",
|
|
6669
7246
|
toolListExports,
|