@primeuicom/mcp 1.1.1 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/service.js CHANGED
@@ -577,6 +577,30 @@ var primeUiExportPageSchema = z3.object({
577
577
  componentsPath: z3.string(),
578
578
  manifest: primeUiExportPageManifestSchema
579
579
  });
580
+ var primeUiPostExportPayloadExportSchema = z3.object({
581
+ id: z3.string(),
582
+ status: primeUiExportStatusSchema,
583
+ createdAt: z3.string().datetime({ offset: true }),
584
+ expiresAt: z3.string().datetime({ offset: true }).nullable(),
585
+ summary: primeUiExportSummarySchema,
586
+ exportables: z3.array(primeUiExportedExportableSchema)
587
+ });
588
+ var primeUiComponentExportComponentSchema = z3.object({
589
+ componentId: z3.string(),
590
+ name: z3.string(),
591
+ pageType: z3.string(),
592
+ family: z3.string(),
593
+ defaultPropsAvailable: z3.boolean(),
594
+ isReadyToExport: z3.boolean()
595
+ });
596
+ var primeUiComponentExportPageSchema = z3.object({
597
+ id: z3.string(),
598
+ title: z3.string().optional(),
599
+ slug: z3.string(),
600
+ pageType: z3.string(),
601
+ isReadyToExport: z3.boolean(),
602
+ manifest: primeUiExportPageManifestSchema
603
+ });
580
604
  var primeUiProjectInfoSchema = z3.object(
581
605
  {
582
606
  projectId: z3.string(),
@@ -654,6 +678,178 @@ var primeUiIssueReportSubmitResponseSchema = z3.object({
654
678
  accepted: z3.literal(true),
655
679
  ticketId: z3.string()
656
680
  });
681
+ var nullableDateStringSchema = z3.string().nullable();
682
+ var primeUiManagedSearchLastErrorSchema = z3.object({
683
+ at: nullableDateStringSchema,
684
+ code: z3.string().nullable(),
685
+ message: z3.string(),
686
+ scope: z3.enum(["project", "index", "job", "sync-run"])
687
+ });
688
+ var primeUiManagedSearchRuntimeModelSchema = z3.object({
689
+ additionalRuntimesSupported: z3.literal(true),
690
+ defaultRuntimeAutoWired: z3.literal(true),
691
+ defaultRuntimeSlug: z3.literal("prod"),
692
+ mode: z3.literal("runtime-first"),
693
+ panelCompatibility: z3.literal("disabled"),
694
+ stagingRuntimeAutoWired: z3.literal(false),
695
+ stagingRuntimeSlug: z3.literal("staging")
696
+ });
697
+ var primeUiManagedSearchRuntimeSchema = z3.object({
698
+ createdAt: z3.string(),
699
+ currentMeilisearchIndexUid: z3.string().nullable(),
700
+ currentQueryId: z3.string().nullable(),
701
+ id: z3.string(),
702
+ lastErrorSummary: z3.string().nullable(),
703
+ lastFailedSyncAt: nullableDateStringSchema,
704
+ lastSuccessfulSyncAt: nullableDateStringSchema,
705
+ name: z3.string(),
706
+ slug: z3.string(),
707
+ status: z3.enum([
708
+ "bootstrapping",
709
+ "active",
710
+ "indexing",
711
+ "failed",
712
+ "inactive"
713
+ ]),
714
+ updatedAt: z3.string()
715
+ });
716
+ var primeUiManagedSearchRootSchema = z3.object({
717
+ bootstrapCompletedAt: nullableDateStringSchema,
718
+ createdAt: nullableDateStringSchema,
719
+ defaultIndexId: z3.string().nullable(),
720
+ defaultSearchId: z3.string().nullable(),
721
+ enabled: z3.boolean(),
722
+ id: z3.string().nullable(),
723
+ lastErrorSummary: z3.string().nullable(),
724
+ lastFailedSyncAt: nullableDateStringSchema,
725
+ lastSuccessfulSyncAt: nullableDateStringSchema,
726
+ status: z3.enum(["inactive", "active", "degraded"]),
727
+ updatedAt: nullableDateStringSchema
728
+ });
729
+ var primeUiManagedSearchSourceSchema = z3.object({
730
+ activationMode: z3.enum(["auto-export", "manual"]),
731
+ configJson: z3.record(z3.unknown()),
732
+ createdAt: z3.string(),
733
+ id: z3.string(),
734
+ sourceKey: z3.string(),
735
+ sourceSnapshotJson: z3.record(z3.unknown()),
736
+ sourceType: z3.enum(["docs", "blog", "landing-pages"]),
737
+ status: z3.enum(["inactive", "active", "blocked"]),
738
+ updatedAt: z3.string()
739
+ });
740
+ var primeUiManagedSearchIndexSchema = z3.object({
741
+ createdAt: z3.string(),
742
+ documentCount: z3.number().int().nonnegative(),
743
+ id: z3.string(),
744
+ kind: z3.enum(["default-runtime", "custom"]),
745
+ lastErrorSummary: z3.string().nullable(),
746
+ lastFailedSyncAt: nullableDateStringSchema,
747
+ lastSuccessfulSyncAt: nullableDateStringSchema,
748
+ meilisearchIndexUid: z3.string().nullable(),
749
+ name: z3.string(),
750
+ publicSearchId: z3.string().nullable(),
751
+ queryRole: z3.enum(["default-runtime", "manual"]),
752
+ retiredAt: nullableDateStringSchema,
753
+ slug: z3.string(),
754
+ sourceSelectionJson: z3.record(z3.unknown()),
755
+ status: z3.enum(["inactive", "syncing", "ready", "failed", "degraded"]),
756
+ updatedAt: z3.string()
757
+ });
758
+ var primeUiManagedSearchJobSchema = z3.object({
759
+ attemptCount: z3.number().int().nonnegative(),
760
+ createdAt: z3.string(),
761
+ errorCode: z3.string().nullable(),
762
+ errorMessage: z3.string().nullable(),
763
+ finishedAt: nullableDateStringSchema,
764
+ id: z3.string(),
765
+ jobType: z3.enum(["sync", "reindex", "recover"]),
766
+ maxAttempts: z3.number().int().nonnegative(),
767
+ projectSearchIndexId: z3.string(),
768
+ requestedById: z3.string().nullable(),
769
+ requestedByType: z3.enum(["export", "studio-user", "cli", "system"]),
770
+ startedAt: nullableDateStringSchema,
771
+ state: z3.enum(["queued", "running", "succeeded", "failed", "cancelled"])
772
+ });
773
+ var primeUiManagedSearchSyncRunSchema = z3.object({
774
+ deletedDocumentCount: z3.number().int().nonnegative(),
775
+ durationMs: z3.number().int().nonnegative().nullable(),
776
+ errorSummary: z3.string().nullable(),
777
+ extractedDocumentCount: z3.number().int().nonnegative(),
778
+ finishedAt: nullableDateStringSchema,
779
+ id: z3.string(),
780
+ projectSearchIndexId: z3.string(),
781
+ projectSearchJobId: z3.string(),
782
+ startedAt: z3.string(),
783
+ status: z3.enum(["running", "succeeded", "failed", "cancelled"]),
784
+ writtenDocumentCount: z3.number().int().nonnegative()
785
+ });
786
+ var primeUiManagedSearchQueryProtectionSchema = z3.object({
787
+ enabled: z3.literal(true),
788
+ rateLimit: z3.object({
789
+ enabled: z3.literal(true),
790
+ windowMs: z3.number().int().positive(),
791
+ maxRequests: z3.number().int().positive(),
792
+ activeBucketCount: z3.number().int().nonnegative(),
793
+ limitedRequestCount: z3.number().int().nonnegative(),
794
+ recentLimitedAt: nullableDateStringSchema
795
+ }),
796
+ logging: z3.object({
797
+ enabled: z3.literal(true),
798
+ lastDayEventCount: z3.number().int().nonnegative(),
799
+ recentEventCount: z3.number().int().nonnegative(),
800
+ lastHourEventCount: z3.number().int().nonnegative(),
801
+ lastEventAt: nullableDateStringSchema
802
+ }),
803
+ cache: z3.object({
804
+ enabled: z3.literal(false),
805
+ ttlMs: z3.null(),
806
+ reason: z3.string()
807
+ })
808
+ });
809
+ var primeUiManagedSearchRelevanceSettingsSchema = z3.object({
810
+ displayedAttributes: z3.array(z3.string()),
811
+ facetSearch: z3.boolean(),
812
+ filterableAttributes: z3.array(z3.string()),
813
+ pagination: z3.object({
814
+ maxTotalHits: z3.number().int().positive()
815
+ }),
816
+ prefixSearch: z3.enum(["indexingTime", "disabled"]),
817
+ primaryKey: z3.string(),
818
+ proximityPrecision: z3.enum(["byWord", "byAttribute"]),
819
+ rankingRules: z3.array(z3.string()),
820
+ searchableAttributes: z3.array(z3.string()),
821
+ sortableAttributes: z3.array(z3.string()),
822
+ typoTolerance: z3.object({
823
+ disableOnAttributes: z3.array(z3.string()),
824
+ enabled: z3.boolean(),
825
+ minWordSizeForTypos: z3.object({
826
+ oneTypo: z3.number().int().positive(),
827
+ twoTypos: z3.number().int().positive()
828
+ })
829
+ })
830
+ });
831
+ var primeUiManagedSearchOverviewResponseSchema = z3.object({
832
+ customIndexes: z3.array(primeUiManagedSearchIndexSchema),
833
+ defaultIndex: primeUiManagedSearchIndexSchema.nullable(),
834
+ lastError: primeUiManagedSearchLastErrorSchema.nullable(),
835
+ projectId: z3.string(),
836
+ queryProtection: primeUiManagedSearchQueryProtectionSchema,
837
+ recentJobs: z3.array(primeUiManagedSearchJobSchema),
838
+ recentSyncRuns: z3.array(primeUiManagedSearchSyncRunSchema),
839
+ relevanceSettings: primeUiManagedSearchRelevanceSettingsSchema,
840
+ runtimeModel: primeUiManagedSearchRuntimeModelSchema,
841
+ runtimes: z3.array(primeUiManagedSearchRuntimeSchema),
842
+ search: primeUiManagedSearchRootSchema,
843
+ sources: z3.array(primeUiManagedSearchSourceSchema),
844
+ success: z3.literal(true)
845
+ });
846
+ var primeUiManagedSearchRuntimeMutationResponseSchema = z3.object({
847
+ success: z3.literal(true),
848
+ runtime: primeUiManagedSearchRuntimeSchema
849
+ });
850
+ var primeUiManagedSearchRuntimeDeleteResponseSchema = z3.object({
851
+ success: z3.literal(true)
852
+ });
657
853
  var primeUiExportsResponseSchema = z3.object({
658
854
  exports: z3.array(
659
855
  z3.object({
@@ -664,17 +860,18 @@ var primeUiExportsResponseSchema = z3.object({
664
860
  )
665
861
  });
666
862
  var primeUiCreateExportResponseSchema = z3.object({
667
- export: z3.object({
668
- id: z3.string(),
669
- status: primeUiExportStatusSchema,
670
- createdAt: z3.string().datetime({ offset: true }),
671
- expiresAt: z3.string().datetime({ offset: true }).nullable(),
672
- summary: primeUiExportSummarySchema,
673
- exportables: z3.array(primeUiExportedExportableSchema)
674
- }),
863
+ export: primeUiPostExportPayloadExportSchema,
675
864
  pages: z3.array(primeUiExportPageSchema)
676
865
  });
677
866
  var primeUiExportManifestSchema = primeUiCreateExportResponseSchema;
867
+ var primeUiComponentExportResponseSchema = z3.object({
868
+ exportId: z3.string(),
869
+ export: primeUiPostExportPayloadExportSchema,
870
+ component: primeUiComponentExportComponentSchema,
871
+ page: primeUiComponentExportPageSchema,
872
+ pages: z3.array(primeUiComponentExportPageSchema)
873
+ });
874
+ var primeUiComponentExportManifestSchema = primeUiComponentExportResponseSchema;
678
875
  function parsePrimeUiExportManifest(value) {
679
876
  if (!value || typeof value !== "object") {
680
877
  throw new Error("Export manifest is invalid.");
@@ -694,6 +891,22 @@ function parsePrimeUiExportManifest(value) {
694
891
  }
695
892
  return parsed.data;
696
893
  }
894
+ function parsePrimeUiComponentExportManifest(value) {
895
+ if (!value || typeof value !== "object") {
896
+ throw new Error("Component export manifest is invalid.");
897
+ }
898
+ const maybe = value;
899
+ if (!maybe.component || typeof maybe.component !== "object") {
900
+ throw new Error("Component export manifest component payload is invalid.");
901
+ }
902
+ const parsed = primeUiComponentExportManifestSchema.safeParse(value);
903
+ if (!parsed.success) {
904
+ throw new Error(
905
+ `Component export manifest is invalid: ${parsed.error.issues.map((issue) => `${issue.path.join(".") || "<root>"} ${issue.message}`).join("; ")}`
906
+ );
907
+ }
908
+ return parsed.data;
909
+ }
697
910
 
698
911
  // src/lib/fs.ts
699
912
  import { mkdir, rm, writeFile } from "fs/promises";
@@ -882,6 +1095,49 @@ var ApiProjectDataProvider = class {
882
1095
  this.buildJsonRequestInit(input)
883
1096
  );
884
1097
  }
1098
+ async getSearchOverview() {
1099
+ return this.requestJson(
1100
+ "project/search",
1101
+ primeUiManagedSearchOverviewResponseSchema
1102
+ );
1103
+ }
1104
+ async createSearchEnvironment(params) {
1105
+ return this.requestJson(
1106
+ "project/search/runtimes",
1107
+ primeUiManagedSearchRuntimeMutationResponseSchema,
1108
+ this.buildJsonRequestInit(params)
1109
+ );
1110
+ }
1111
+ async updateSearchEnvironment(params) {
1112
+ return this.requestJson(
1113
+ `project/search/runtimes/${encodeURIComponent(params.runtimeSlug)}`,
1114
+ primeUiManagedSearchRuntimeMutationResponseSchema,
1115
+ this.buildJsonRequestInit(
1116
+ {
1117
+ projectId: params.projectId,
1118
+ ...params.name === void 0 ? {} : { name: params.name },
1119
+ ...params.status === void 0 ? {} : { status: params.status }
1120
+ },
1121
+ {
1122
+ method: "PATCH"
1123
+ }
1124
+ )
1125
+ );
1126
+ }
1127
+ async deleteSearchEnvironment(params) {
1128
+ return this.requestJson(
1129
+ `project/search/runtimes/${encodeURIComponent(params.runtimeSlug)}`,
1130
+ primeUiManagedSearchRuntimeDeleteResponseSchema,
1131
+ this.buildJsonRequestInit(
1132
+ {
1133
+ projectId: params.projectId
1134
+ },
1135
+ {
1136
+ method: "DELETE"
1137
+ }
1138
+ )
1139
+ );
1140
+ }
885
1141
  async getProjectPageBySlug(slug) {
886
1142
  const encodedSlug = encodeURIComponent(slug);
887
1143
  return this.requestJson(
@@ -905,9 +1161,19 @@ var ApiProjectDataProvider = class {
905
1161
  }
906
1162
  );
907
1163
  }
1164
+ async createComponentExport(componentId) {
1165
+ return this.requestJson(
1166
+ `component-registry/components/${encodeURIComponent(componentId)}/exports`,
1167
+ primeUiComponentExportResponseSchema,
1168
+ {
1169
+ method: "POST"
1170
+ }
1171
+ );
1172
+ }
908
1173
  /**
909
1174
  * Consumer-side runtime contract for GET /api/v1/project/exports/:exportId/download.
910
- * Producer source of truth: apps/studio/src/app/api/v1/project/exports/[exportId]/download/route.ts
1175
+ * Primary Studio runtime entrypoint: apps/studio/src/tanstack/routes/api.v1.project.exports.$exportId.download.ts
1176
+ * Legacy migration reference: apps/studio/src/app/api/v1/project/exports/[exportId]/download/route.ts
911
1177
  * Keep content-type and archive format checks synchronized with the producer response.
912
1178
  */
913
1179
  async downloadExportArchive(exportId, destinationPath) {
@@ -951,10 +1217,12 @@ var ApiProjectDataProvider = class {
951
1217
  buildUrl(endpoint) {
952
1218
  return buildPrimeUiApiUrl(this.apiRoot, endpoint);
953
1219
  }
954
- buildJsonRequestInit(payload) {
1220
+ buildJsonRequestInit(payload, overrides = {}) {
955
1221
  return {
956
- method: "POST",
1222
+ ...overrides,
1223
+ method: overrides.method ?? "POST",
957
1224
  headers: {
1225
+ ...overrides.headers ?? {},
958
1226
  "Content-Type": "application/json"
959
1227
  },
960
1228
  body: JSON.stringify(payload)
@@ -1725,11 +1993,11 @@ async function runHealthCheck(options) {
1725
1993
  }
1726
1994
 
1727
1995
  // src/services/project-sync-service.ts
1728
- import path13 from "path";
1729
- import { readFile as readFile7 } from "fs/promises";
1996
+ import path14 from "path";
1997
+ import { readFile as readFile8 } from "fs/promises";
1730
1998
 
1731
1999
  // src/services/page-copy-service.ts
1732
- import { readFile as readFile4, stat as stat6, writeFile as writeFile2 } from "fs/promises";
2000
+ import { readFile as readFile4, stat as stat6, writeFile as writeFile3 } from "fs/promises";
1733
2001
  import path10 from "path";
1734
2002
 
1735
2003
  // src/lib/import-graph.ts
@@ -2011,7 +2279,7 @@ function buildUnifiedDiff(input) {
2011
2279
  }
2012
2280
 
2013
2281
  // src/services/copy-service-shared.ts
2014
- import { readFile as readFile3, readdir as readdir2, stat as stat5 } from "fs/promises";
2282
+ import { readFile as readFile3, readdir as readdir2, stat as stat5, writeFile as writeFile2 } from "fs/promises";
2015
2283
  import path9 from "path";
2016
2284
  var DEPENDENCY_SECTIONS = [
2017
2285
  "dependencies",
@@ -2198,6 +2466,64 @@ async function resolveDependencyRequirements(input) {
2198
2466
  )
2199
2467
  };
2200
2468
  }
2469
+ async function applyDependencyRequirementsToPackageJson(input) {
2470
+ const exportPackageJson = await readJsonFile(
2471
+ input.exportPackageJsonPath
2472
+ );
2473
+ const userPackageJson = await readJsonFile(
2474
+ input.userPackageJsonPath
2475
+ );
2476
+ const addedDependencies = [];
2477
+ const dependenciesVersionConflicts = [];
2478
+ for (const packageName of new Set(input.requiredPackageNames)) {
2479
+ const exportDependency = getDependencyVersion(
2480
+ exportPackageJson,
2481
+ packageName
2482
+ );
2483
+ if (!exportDependency) {
2484
+ continue;
2485
+ }
2486
+ const userDependency = getDependencyVersion(userPackageJson, packageName);
2487
+ if (!userDependency) {
2488
+ const sectionData = getOrCreateDependencySection(
2489
+ userPackageJson,
2490
+ exportDependency.section
2491
+ );
2492
+ sectionData[packageName] = exportDependency.version;
2493
+ addedDependencies.push({
2494
+ packageName,
2495
+ version: exportDependency.version,
2496
+ section: exportDependency.section
2497
+ });
2498
+ continue;
2499
+ }
2500
+ if (userDependency.version !== exportDependency.version) {
2501
+ dependenciesVersionConflicts.push({
2502
+ packageName,
2503
+ section: exportDependency.section,
2504
+ exportVersion: exportDependency.version,
2505
+ userVersion: userDependency.version
2506
+ });
2507
+ }
2508
+ }
2509
+ if (addedDependencies.length > 0) {
2510
+ sortDependencySections(userPackageJson);
2511
+ await writeFile2(
2512
+ input.userPackageJsonPath,
2513
+ `${JSON.stringify(userPackageJson, null, 2)}
2514
+ `,
2515
+ "utf-8"
2516
+ );
2517
+ }
2518
+ return {
2519
+ addedDependencies: addedDependencies.sort(
2520
+ (a, b) => a.packageName.localeCompare(b.packageName)
2521
+ ),
2522
+ dependenciesVersionConflicts: dependenciesVersionConflicts.sort(
2523
+ (a, b) => a.packageName.localeCompare(b.packageName)
2524
+ )
2525
+ };
2526
+ }
2201
2527
 
2202
2528
  // src/services/runtime-guidance.ts
2203
2529
  var EXPORT_MANIFEST_DESCRIPTION = "Local sidecar export manifest. This is the authoritative file-level contract for the selected transfer item. Files listed per page or exportable are functionality-critical dependencies for that item.";
@@ -2367,7 +2693,7 @@ async function copyPageFromExport(input) {
2367
2693
  const targetRelative = toProjectRelative(input.projectRoot, targetFilePath);
2368
2694
  if (!targetBuffer) {
2369
2695
  await ensureDir(path10.dirname(targetFilePath));
2370
- await writeFile2(targetFilePath, plannedSourceBuffer);
2696
+ await writeFile3(targetFilePath, plannedSourceBuffer);
2371
2697
  newFiles.push(targetRelative);
2372
2698
  continue;
2373
2699
  }
@@ -2436,7 +2762,7 @@ async function copyPageFromExport(input) {
2436
2762
  }
2437
2763
  if (addedDependencies.length > 0) {
2438
2764
  sortDependencySections(userPackageJson);
2439
- await writeFile2(
2765
+ await writeFile3(
2440
2766
  userPackageJsonPath,
2441
2767
  `${JSON.stringify(userPackageJson, null, 2)}
2442
2768
  `,
@@ -2472,7 +2798,7 @@ async function copyPageFromExport(input) {
2472
2798
  sourceComponentsPath: page.componentsPath,
2473
2799
  conflicts: sortedConflictReportEntries
2474
2800
  };
2475
- await writeFile2(reportPath, `${JSON.stringify(report, null, 2)}
2801
+ await writeFile3(reportPath, `${JSON.stringify(report, null, 2)}
2476
2802
  `, "utf-8");
2477
2803
  const hasFileConflicts = conflictFiles.length > 0;
2478
2804
  const hasDependencyVersionConflicts = sortedDependenciesVersionConflicts.length > 0;
@@ -2622,7 +2948,7 @@ function buildInspectPageReport(input) {
2622
2948
  }
2623
2949
 
2624
2950
  // src/services/exportable-copy-service.ts
2625
- import { readFile as readFile5, writeFile as writeFile3 } from "fs/promises";
2951
+ import { readFile as readFile5, writeFile as writeFile4 } from "fs/promises";
2626
2952
  import path11 from "path";
2627
2953
  var PACKAGE_JSON_RELATIVE_PATH = "package.json";
2628
2954
  var SUPPLEMENTARY_DEPENDENCY_PACKAGES = {
@@ -2768,7 +3094,7 @@ async function copyExportableFromExport(input) {
2768
3094
  const targetRelative = toProjectRelative(input.projectRoot, targetFilePath);
2769
3095
  if (!targetBuffer) {
2770
3096
  await ensureDir(path11.dirname(targetFilePath));
2771
- await writeFile3(targetFilePath, sourceBuffer);
3097
+ await writeFile4(targetFilePath, sourceBuffer);
2772
3098
  newFiles.push(targetRelative);
2773
3099
  continue;
2774
3100
  }
@@ -2834,7 +3160,7 @@ async function copyExportableFromExport(input) {
2834
3160
  exportableKey: normalizedExportableKey,
2835
3161
  conflicts: sortedConflictReportEntries
2836
3162
  };
2837
- await writeFile3(reportPath, `${JSON.stringify(report, null, 2)}
3163
+ await writeFile4(reportPath, `${JSON.stringify(report, null, 2)}
2838
3164
  `, "utf-8");
2839
3165
  const hasFileConflicts = conflictFiles.length > 0;
2840
3166
  const hasDependencyVersionConflicts = dependenciesVersionConflicts.length > 0;
@@ -2895,7 +3221,7 @@ async function copyExportableFromExport(input) {
2895
3221
  }
2896
3222
 
2897
3223
  // src/services/component-copy-service.ts
2898
- import { readFile as readFile6, stat as stat7, writeFile as writeFile4 } from "fs/promises";
3224
+ import { readFile as readFile6, stat as stat7, writeFile as writeFile5 } from "fs/promises";
2899
3225
  import path12 from "path";
2900
3226
  function normalizeSlug2(slug) {
2901
3227
  const trimmed = slug.trim();
@@ -3051,7 +3377,7 @@ async function applyDependencyRequirements(input) {
3051
3377
  }
3052
3378
  if (addedDependencies.length > 0) {
3053
3379
  sortDependencySections(userPackageJson);
3054
- await writeFile4(
3380
+ await writeFile5(
3055
3381
  userPackageJsonPath,
3056
3382
  `${JSON.stringify(userPackageJson, null, 2)}
3057
3383
  `,
@@ -3215,7 +3541,7 @@ async function copyComponentFromExport(input) {
3215
3541
  }
3216
3542
  if (!targetBuffer) {
3217
3543
  await ensureDir(path12.dirname(targetPrimaryPath));
3218
- await writeFile4(targetPrimaryPath, sourceBuffer);
3544
+ await writeFile5(targetPrimaryPath, sourceBuffer);
3219
3545
  newFiles.push(primaryComponentFile);
3220
3546
  } else if (sourceBuffer.equals(targetBuffer)) {
3221
3547
  identicalFiles.push(primaryComponentFile);
@@ -3319,7 +3645,7 @@ async function copyComponentFromExport(input) {
3319
3645
  potentialConflicts: sortedPotentialConflictEntries,
3320
3646
  selectedBlock
3321
3647
  };
3322
- await writeFile4(reportPath, `${JSON.stringify(report, null, 2)}
3648
+ await writeFile5(reportPath, `${JSON.stringify(report, null, 2)}
3323
3649
  `, "utf-8");
3324
3650
  const needsReview = !primaryComponentFile || conflictFiles.length > 0 || dependenciesVersionConflicts.length > 0 || missingManifestFiles.size > 0;
3325
3651
  const missingManifestFileList = [...missingManifestFiles].sort(
@@ -3408,71 +3734,568 @@ async function copyComponentFromExport(input) {
3408
3734
  };
3409
3735
  }
3410
3736
 
3411
- // src/services/project-sync-service.ts
3412
- function buildManifestPath(exportsRoot, exportId) {
3413
- return path13.join(exportsRoot, `${exportId}.manifest.json`);
3737
+ // src/services/registry-component-copy-service.ts
3738
+ import { readFile as readFile7, writeFile as writeFile6 } from "fs/promises";
3739
+ import path13 from "path";
3740
+ var PACKAGE_JSON_RELATIVE_PATH2 = "package.json";
3741
+ var VIRTUAL_ROUTE_SEGMENT = "__primeui-component-export";
3742
+ var COMPONENT_PAGES_PREFIX = "src/components/pages/";
3743
+ var COMPONENT_UI_PREFIX = "src/components/ui/";
3744
+ function normalizeComponentId(componentId) {
3745
+ const trimmed = componentId.trim();
3746
+ if (!trimmed) {
3747
+ throw new Error("componentId must not be empty.");
3748
+ }
3749
+ return trimmed;
3414
3750
  }
3415
- function normalizeSlug3(slug) {
3416
- const trimmed = slug.trim();
3417
- if (!trimmed || trimmed === "/") {
3418
- return "/";
3751
+ function normalizeManifestFilePath(filePath) {
3752
+ const trimmed = filePath.trim();
3753
+ if (!trimmed) {
3754
+ throw new Error("Component export manifest contains an empty file path.");
3419
3755
  }
3420
- const withLeadingSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
3421
- return withLeadingSlash.replace(/\/+$/, "") || "/";
3756
+ return toPosixPath(trimmed).replace(/^\.\/+/, "");
3422
3757
  }
3423
- var ProjectSyncService = class {
3424
- provider;
3425
- projectRoot;
3426
- targetProjectRoot;
3427
- primeUiRoot;
3428
- tempRoot;
3429
- exportsRoot;
3430
- pageDetailsBySlug;
3431
- constructor(options) {
3432
- this.projectRoot = options.projectRoot;
3433
- this.targetProjectRoot = options.targetProjectRoot;
3434
- this.provider = options.provider;
3435
- this.pageDetailsBySlug = options.pageDetailsBySlug ?? /* @__PURE__ */ new Map();
3436
- this.primeUiRoot = path13.join(this.projectRoot, ".primeui");
3437
- this.tempRoot = path13.join(this.primeUiRoot, "temp");
3438
- this.exportsRoot = path13.join(this.tempRoot, "exports");
3758
+ function uniqueNormalizedManifestFiles(files) {
3759
+ return [...new Set(files.map(normalizeManifestFilePath))];
3760
+ }
3761
+ function getSuccessfulExportableFiles(manifest) {
3762
+ return manifest.export.exportables.flatMap(
3763
+ (exportable) => exportable.isReadyToExport && exportable.manifest.success ? exportable.manifest.files : []
3764
+ );
3765
+ }
3766
+ function getComponentCopyManifestFiles(manifest) {
3767
+ return uniqueNormalizedManifestFiles([
3768
+ ...manifest.page.manifest.files,
3769
+ ...getSuccessfulExportableFiles(manifest)
3770
+ ]);
3771
+ }
3772
+ function isVirtualRouteFile(relativePath) {
3773
+ const segments = relativePath.split("/");
3774
+ return segments[0] === "src" && segments[1] === "app" && segments.includes(VIRTUAL_ROUTE_SEGMENT);
3775
+ }
3776
+ function isComponentEntryFile(relativePath, componentId) {
3777
+ if (!relativePath.startsWith(COMPONENT_PAGES_PREFIX)) {
3778
+ return false;
3439
3779
  }
3440
- async getProjectInfo(_context) {
3441
- await this.ensureTempLayout();
3442
- return this.provider.getProjectInfo();
3780
+ const extension = path13.extname(relativePath);
3781
+ if (!extension) {
3782
+ return false;
3443
3783
  }
3444
- async getProjectDescription(_context) {
3445
- return this.provider.getProjectDescription();
3784
+ const basename = path13.basename(relativePath, extension);
3785
+ if (basename === componentId) {
3786
+ return true;
3446
3787
  }
3447
- async upsertProjectDescription(projectDescription, _context) {
3448
- return this.provider.upsertProjectDescription(projectDescription);
3788
+ return basename === "index" && path13.basename(path13.dirname(relativePath)) === componentId;
3789
+ }
3790
+ function isManifestSupportFile(relativePath) {
3791
+ return relativePath.startsWith(COMPONENT_UI_PREFIX);
3792
+ }
3793
+ function toSkippedFile(targetPath, reason) {
3794
+ return {
3795
+ targetPath,
3796
+ reason
3797
+ };
3798
+ }
3799
+ function splitManifestFiles(input) {
3800
+ const manifestFiles = input.files.map(normalizeManifestFilePath);
3801
+ const copyableFileSet = new Set(input.copyableFiles);
3802
+ const componentEntryFiles = [];
3803
+ const skippedFiles = [];
3804
+ for (const relativePath of manifestFiles) {
3805
+ if (relativePath === PACKAGE_JSON_RELATIVE_PATH2) {
3806
+ skippedFiles.push(
3807
+ toSkippedFile(relativePath, "package_json_managed_as_dependencies")
3808
+ );
3809
+ continue;
3810
+ }
3811
+ if (isVirtualRouteFile(relativePath)) {
3812
+ skippedFiles.push(toSkippedFile(relativePath, "virtual_component_route"));
3813
+ continue;
3814
+ }
3815
+ if (isComponentEntryFile(relativePath, input.componentId)) {
3816
+ componentEntryFiles.push(relativePath);
3817
+ }
3818
+ if (!copyableFileSet.has(relativePath)) {
3819
+ skippedFiles.push(
3820
+ toSkippedFile(relativePath, "not_component_dependency")
3821
+ );
3822
+ }
3449
3823
  }
3450
- async listProjectPages(_context) {
3451
- return this.provider.listProjectPages();
3824
+ return {
3825
+ manifestFiles,
3826
+ componentEntryFiles,
3827
+ skippedFiles
3828
+ };
3829
+ }
3830
+ async function createConflictReportEntry2(input) {
3831
+ const sourceBuffer = await readFile7(input.sourceFilePath);
3832
+ let targetBuffer = null;
3833
+ try {
3834
+ targetBuffer = await readFile7(input.targetFilePath);
3835
+ } catch {
3836
+ targetBuffer = null;
3452
3837
  }
3453
- async getProjectPage(pageId, _context) {
3454
- return this.provider.getProjectPage(pageId);
3838
+ if (!targetBuffer || sourceBuffer.equals(targetBuffer)) {
3839
+ return null;
3455
3840
  }
3456
- async createProjectPage(input, _context) {
3457
- return this.provider.createProjectPage(input);
3841
+ const sourceRelative = toProjectRelative(
3842
+ input.exportPath,
3843
+ input.sourceFilePath
3844
+ );
3845
+ const targetRelative = toProjectRelative(
3846
+ input.projectRoot,
3847
+ input.targetFilePath
3848
+ );
3849
+ const isBinary = isBinaryBuffer(sourceBuffer) || isBinaryBuffer(targetBuffer);
3850
+ return {
3851
+ sourcePath: sourceRelative,
3852
+ targetPath: targetRelative,
3853
+ diff: isBinary ? "Binary files differ." : buildUnifiedDiff({
3854
+ oldText: targetBuffer.toString("utf-8"),
3855
+ newText: sourceBuffer.toString("utf-8"),
3856
+ oldLabel: `user/${targetRelative}`,
3857
+ newLabel: `export/${sourceRelative}`
3858
+ }),
3859
+ isBinary
3860
+ };
3861
+ }
3862
+ function buildMessage(input) {
3863
+ const parts = [
3864
+ input.status === "completed" ? `Registry component "${input.componentId}" copied from the component manifest.` : `Registry component "${input.componentId}" needs review before transfer is complete.`,
3865
+ `Report: ${input.reportPath}.`
3866
+ ];
3867
+ if (input.newFiles.length > 0) {
3868
+ parts.push(`${input.newFiles.length} new file(s) copied.`);
3458
3869
  }
3459
- async listProjectPageVariants(pageId, _context) {
3460
- return this.provider.listProjectPageVariants(pageId);
3870
+ if (input.identicalFiles.length > 0) {
3871
+ parts.push(`${input.identicalFiles.length} file(s) already identical.`);
3461
3872
  }
3462
- async getProjectPageVariant(pageId, variantId, _context) {
3463
- return this.provider.getProjectPageVariant(pageId, variantId);
3873
+ if (input.conflictFiles.length > 0) {
3874
+ parts.push(
3875
+ `${input.conflictFiles.length} conflicting file(s) were not overwritten.`
3876
+ );
3464
3877
  }
3465
- async createProjectPageVariant(pageId, input, _context) {
3466
- return this.provider.createProjectPageVariant(pageId, input);
3878
+ if (input.skippedFiles.length > 0) {
3879
+ parts.push(
3880
+ `${input.skippedFiles.length} manifest file(s) skipped, including virtual route, package metadata, or non-component context entries.`
3881
+ );
3467
3882
  }
3468
- async setProjectPageActiveVariant(pageId, variantId, _context) {
3469
- return this.provider.setProjectPageActiveVariant(pageId, variantId);
3883
+ if (input.missingManifestFiles.length > 0) {
3884
+ parts.push(
3885
+ `Missing manifest file(s): ${input.missingManifestFiles.join(", ")}.`
3886
+ );
3470
3887
  }
3471
- async submitIssueReport(input, _context) {
3472
- return this.provider.submitIssueReport(input);
3888
+ if (input.addedDependenciesCount > 0) {
3889
+ parts.push(
3890
+ "Missing dependencies were added to package.json but are NOT installed."
3891
+ );
3473
3892
  }
3474
- async listExports(_context) {
3475
- await this.ensureTempLayout();
3893
+ if (input.dependencyConflictCount > 0) {
3894
+ parts.push(
3895
+ "Dependency version conflicts require manual resolution before completion."
3896
+ );
3897
+ }
3898
+ parts.push(
3899
+ "The virtual component export page was skipped; manually insert the copied component into a real target page."
3900
+ );
3901
+ return parts.join(" ");
3902
+ }
3903
+ async function copyRegistryComponentFromExport(input) {
3904
+ const normalizedComponentId = normalizeComponentId(input.componentId);
3905
+ const { exportId, exportPath } = await resolveSingleExportDirectory(
3906
+ input.exportsRoot
3907
+ );
3908
+ const manifestPath = path13.join(
3909
+ input.exportsRoot,
3910
+ `${exportId}.manifest.json`
3911
+ );
3912
+ if (!await fileExists2(manifestPath)) {
3913
+ throw new Error(
3914
+ `Component export manifest is missing at ${manifestPath}. Run create_component_export and download_component_export to regenerate it.`
3915
+ );
3916
+ }
3917
+ const manifest = parsePrimeUiComponentExportManifest(
3918
+ await readJsonFile(manifestPath)
3919
+ );
3920
+ if (manifest.export.id !== exportId || manifest.exportId !== exportId) {
3921
+ throw new Error(
3922
+ `Component export manifest mismatch for id "${exportId}". Run create_component_export and download_component_export again.`
3923
+ );
3924
+ }
3925
+ if (manifest.component.componentId !== normalizedComponentId) {
3926
+ throw new Error(
3927
+ `Component export manifest mismatch: expected componentId "${normalizedComponentId}", got "${manifest.component.componentId}".`
3928
+ );
3929
+ }
3930
+ const initialSelection = splitManifestFiles({
3931
+ files: getComponentCopyManifestFiles(manifest),
3932
+ componentId: normalizedComponentId,
3933
+ copyableFiles: []
3934
+ });
3935
+ const manifestFileSet = new Set(initialSelection.manifestFiles);
3936
+ const componentEntryCandidates = await resolveManifestCandidateFiles({
3937
+ exportPath,
3938
+ manifestOwnerLabel: `registry component "${normalizedComponentId}"`,
3939
+ files: initialSelection.componentEntryFiles,
3940
+ requireExisting: false
3941
+ });
3942
+ const newFiles = [];
3943
+ const identicalFiles = [];
3944
+ const conflictFiles = [];
3945
+ const conflictReportEntries = [];
3946
+ const missingManifestFiles = /* @__PURE__ */ new Set();
3947
+ const existingComponentEntryFiles = [];
3948
+ for (const sourceFilePath of componentEntryCandidates) {
3949
+ const relativeToExport = toProjectRelative(exportPath, sourceFilePath);
3950
+ if (await fileExists2(sourceFilePath)) {
3951
+ existingComponentEntryFiles.push(sourceFilePath);
3952
+ continue;
3953
+ }
3954
+ missingManifestFiles.add(relativeToExport);
3955
+ }
3956
+ const dependencyGraph = existingComponentEntryFiles.length > 0 ? await buildImportGraph({
3957
+ projectRoot: exportPath,
3958
+ entryFiles: existingComponentEntryFiles,
3959
+ followInternalImports: true
3960
+ }) : { internalFiles: [], externalPackages: [] };
3961
+ const graphInternalFiles = new Set(
3962
+ dependencyGraph.internalFiles.map(
3963
+ (filePath) => toProjectRelative(exportPath, filePath)
3964
+ )
3965
+ );
3966
+ const exportableFileSet = new Set(
3967
+ uniqueNormalizedManifestFiles(getSuccessfulExportableFiles(manifest))
3968
+ );
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
+ const { manifestFiles, skippedFiles } = splitManifestFiles({
3975
+ files: initialSelection.manifestFiles,
3976
+ componentId: normalizedComponentId,
3977
+ copyableFiles
3978
+ });
3979
+ const candidateFiles = await resolveManifestCandidateFiles({
3980
+ exportPath,
3981
+ manifestOwnerLabel: `registry component "${normalizedComponentId}"`,
3982
+ files: copyableFiles,
3983
+ requireExisting: false
3984
+ });
3985
+ for (const sourceFilePath of candidateFiles) {
3986
+ const relativeToExport = toProjectRelative(exportPath, sourceFilePath);
3987
+ const sourceExists = await fileExists2(sourceFilePath);
3988
+ if (!sourceExists) {
3989
+ missingManifestFiles.add(relativeToExport);
3990
+ continue;
3991
+ }
3992
+ const targetFilePath = path13.join(input.projectRoot, relativeToExport);
3993
+ ensureSafeTargetPath(input.projectRoot, targetFilePath);
3994
+ const sourceBuffer = await readFile7(sourceFilePath);
3995
+ let targetBuffer = null;
3996
+ try {
3997
+ targetBuffer = await readFile7(targetFilePath);
3998
+ } catch {
3999
+ targetBuffer = null;
4000
+ }
4001
+ if (!targetBuffer) {
4002
+ await ensureDir(path13.dirname(targetFilePath));
4003
+ await writeFile6(targetFilePath, sourceBuffer);
4004
+ newFiles.push(relativeToExport);
4005
+ continue;
4006
+ }
4007
+ if (sourceBuffer.equals(targetBuffer)) {
4008
+ identicalFiles.push(relativeToExport);
4009
+ continue;
4010
+ }
4011
+ const entry = await createConflictReportEntry2({
4012
+ sourceFilePath,
4013
+ targetFilePath,
4014
+ exportPath,
4015
+ projectRoot: input.projectRoot
4016
+ });
4017
+ if (entry) {
4018
+ conflictReportEntries.push(entry);
4019
+ conflictFiles.push({
4020
+ targetPath: entry.targetPath,
4021
+ isBinary: entry.isBinary
4022
+ });
4023
+ }
4024
+ }
4025
+ const { addedDependencies, dependenciesVersionConflicts } = await applyDependencyRequirementsToPackageJson({
4026
+ exportPackageJsonPath: path13.join(exportPath, PACKAGE_JSON_RELATIVE_PATH2),
4027
+ userPackageJsonPath: path13.join(
4028
+ input.projectRoot,
4029
+ PACKAGE_JSON_RELATIVE_PATH2
4030
+ ),
4031
+ requiredPackageNames: dependencyGraph.externalPackages
4032
+ });
4033
+ const missingManifestFileList = [...missingManifestFiles].sort(
4034
+ (a, b) => a.localeCompare(b)
4035
+ );
4036
+ const sortedConflictEntries = conflictReportEntries.sort(
4037
+ (a, b) => a.targetPath.localeCompare(b.targetPath)
4038
+ );
4039
+ const sortedConflictFiles = conflictFiles.sort(
4040
+ (a, b) => a.targetPath.localeCompare(b.targetPath)
4041
+ );
4042
+ const sortedNewFiles = newFiles.sort((a, b) => a.localeCompare(b));
4043
+ const sortedIdenticalFiles = identicalFiles.sort(
4044
+ (a, b) => a.localeCompare(b)
4045
+ );
4046
+ const copyId = createCopyId();
4047
+ const reportPath = path13.join(
4048
+ input.exportsRoot,
4049
+ `${exportId}.copy-registry-component-report-${copyId}.json`
4050
+ );
4051
+ const report = {
4052
+ reportPath,
4053
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
4054
+ exportId,
4055
+ componentId: normalizedComponentId,
4056
+ manifestFiles,
4057
+ copyableFiles,
4058
+ skippedFiles,
4059
+ conflicts: sortedConflictEntries,
4060
+ missingManifestFiles: missingManifestFileList
4061
+ };
4062
+ await writeFile6(reportPath, `${JSON.stringify(report, null, 2)}
4063
+ `, "utf-8");
4064
+ const needsReview = copyableFiles.length === 0 || sortedConflictFiles.length > 0 || dependenciesVersionConflicts.length > 0 || missingManifestFileList.length > 0;
4065
+ const status = needsReview ? "needs_review" : "completed";
4066
+ const guidanceArtifacts = [
4067
+ buildExportManifestArtifact(manifestPath),
4068
+ buildReferenceExportArtifact(exportPath)
4069
+ ];
4070
+ if (needsReview) {
4071
+ guidanceArtifacts.push(buildConflictReportArtifact(reportPath));
4072
+ }
4073
+ return {
4074
+ status,
4075
+ message: buildMessage({
4076
+ componentId: normalizedComponentId,
4077
+ status,
4078
+ reportPath,
4079
+ newFiles: sortedNewFiles,
4080
+ identicalFiles: sortedIdenticalFiles,
4081
+ conflictFiles: sortedConflictFiles,
4082
+ skippedFiles,
4083
+ addedDependenciesCount: addedDependencies.length,
4084
+ dependencyConflictCount: dependenciesVersionConflicts.length,
4085
+ missingManifestFiles: missingManifestFileList
4086
+ }),
4087
+ reportPath,
4088
+ exportId,
4089
+ exportPath,
4090
+ manifestPath,
4091
+ component: manifest.component,
4092
+ manifestFiles,
4093
+ copyableFiles,
4094
+ newFiles: sortedNewFiles,
4095
+ identicalFiles: sortedIdenticalFiles,
4096
+ conflictFiles: sortedConflictFiles,
4097
+ skippedFiles,
4098
+ addedDependencies,
4099
+ dependenciesVersionConflicts,
4100
+ missingManifestFiles: missingManifestFileList,
4101
+ summary: {
4102
+ totalManifestFiles: manifestFiles.length,
4103
+ totalCopyableFiles: copyableFiles.length,
4104
+ copiedFiles: sortedNewFiles.length,
4105
+ identicalFiles: sortedIdenticalFiles.length,
4106
+ conflictFiles: sortedConflictFiles.length,
4107
+ skippedFiles: skippedFiles.length,
4108
+ addedDependencies: addedDependencies.length,
4109
+ dependenciesVersionConflicts: dependenciesVersionConflicts.length,
4110
+ missingManifestFiles: missingManifestFileList.length
4111
+ },
4112
+ guidance: {
4113
+ artifacts: guidanceArtifacts,
4114
+ requiredActions: "Do not install the skipped virtual component export page as a route. Manually import the copied component/support files 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
+ }
4116
+ };
4117
+ }
4118
+
4119
+ // src/services/project-sync-service.ts
4120
+ function buildManifestPath(exportsRoot, exportId) {
4121
+ return path14.join(exportsRoot, `${exportId}.manifest.json`);
4122
+ }
4123
+ function normalizeSlug3(slug) {
4124
+ const trimmed = slug.trim();
4125
+ if (!trimmed || trimmed === "/") {
4126
+ return "/";
4127
+ }
4128
+ const withLeadingSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
4129
+ return withLeadingSlash.replace(/\/+$/, "") || "/";
4130
+ }
4131
+ function normalizeEnvironmentSlug(slug) {
4132
+ return slug.trim();
4133
+ }
4134
+ var ProjectSyncService = class {
4135
+ provider;
4136
+ projectRoot;
4137
+ targetProjectRoot;
4138
+ primeUiRoot;
4139
+ tempRoot;
4140
+ exportsRoot;
4141
+ pageDetailsBySlug;
4142
+ constructor(options) {
4143
+ this.projectRoot = options.projectRoot;
4144
+ this.targetProjectRoot = options.targetProjectRoot;
4145
+ this.provider = options.provider;
4146
+ this.pageDetailsBySlug = options.pageDetailsBySlug ?? /* @__PURE__ */ new Map();
4147
+ this.primeUiRoot = path14.join(this.projectRoot, ".primeui");
4148
+ this.tempRoot = path14.join(this.primeUiRoot, "temp");
4149
+ this.exportsRoot = path14.join(this.tempRoot, "exports");
4150
+ }
4151
+ async getProjectInfo(_context) {
4152
+ await this.ensureTempLayout();
4153
+ return this.provider.getProjectInfo();
4154
+ }
4155
+ async getProjectDescription(_context) {
4156
+ return this.provider.getProjectDescription();
4157
+ }
4158
+ async upsertProjectDescription(projectDescription, _context) {
4159
+ return this.provider.upsertProjectDescription(projectDescription);
4160
+ }
4161
+ async listProjectPages(_context) {
4162
+ return this.provider.listProjectPages();
4163
+ }
4164
+ async getProjectPage(pageId, _context) {
4165
+ return this.provider.getProjectPage(pageId);
4166
+ }
4167
+ async createProjectPage(input, _context) {
4168
+ return this.provider.createProjectPage(input);
4169
+ }
4170
+ async listProjectPageVariants(pageId, _context) {
4171
+ return this.provider.listProjectPageVariants(pageId);
4172
+ }
4173
+ async getProjectPageVariant(pageId, variantId, _context) {
4174
+ return this.provider.getProjectPageVariant(pageId, variantId);
4175
+ }
4176
+ async createProjectPageVariant(pageId, input, _context) {
4177
+ return this.provider.createProjectPageVariant(pageId, input);
4178
+ }
4179
+ async setProjectPageActiveVariant(pageId, variantId, _context) {
4180
+ return this.provider.setProjectPageActiveVariant(pageId, variantId);
4181
+ }
4182
+ async submitIssueReport(input, _context) {
4183
+ return this.provider.submitIssueReport(input);
4184
+ }
4185
+ async getSearchOverview(_context) {
4186
+ return this.provider.getSearchOverview();
4187
+ }
4188
+ async getSearchEnvironment(environmentSlug, _context) {
4189
+ const normalizedSlug = normalizeEnvironmentSlug(environmentSlug);
4190
+ if (!normalizedSlug) {
4191
+ throw new Error("Search environment slug is required.");
4192
+ }
4193
+ const overview = await this.provider.getSearchOverview();
4194
+ const runtime = overview.runtimes.find(
4195
+ (candidate) => candidate.slug === normalizedSlug
4196
+ );
4197
+ if (!runtime) {
4198
+ throw new Error(
4199
+ `Search environment "${normalizedSlug}" was not found in the current project overview.`
4200
+ );
4201
+ }
4202
+ const relatedIndexes = this.getRelatedIndexesForRuntime(overview, runtime);
4203
+ const relatedIndexIds = new Set(relatedIndexes.map((index) => index.id));
4204
+ const primaryIndex = relatedIndexes[0] ?? null;
4205
+ return {
4206
+ success: true,
4207
+ environmentSlug: normalizedSlug,
4208
+ environment: runtime,
4209
+ primaryIndex,
4210
+ relatedIndexes,
4211
+ recentJobs: overview.recentJobs.filter(
4212
+ (job) => relatedIndexIds.has(job.projectSearchIndexId)
4213
+ ),
4214
+ recentSyncRuns: overview.recentSyncRuns.filter(
4215
+ (syncRun) => relatedIndexIds.has(syncRun.projectSearchIndexId)
4216
+ ),
4217
+ search: overview.search,
4218
+ runtimeModel: overview.runtimeModel,
4219
+ sources: overview.sources,
4220
+ lastError: overview.lastError
4221
+ };
4222
+ }
4223
+ async createSearchEnvironment(input, _context) {
4224
+ const projectInfo = await this.provider.getProjectInfo();
4225
+ const result = await this.provider.createSearchEnvironment({
4226
+ name: input.name,
4227
+ projectId: projectInfo.projectId,
4228
+ slug: input.slug
4229
+ });
4230
+ return {
4231
+ success: result.success,
4232
+ environment: result.runtime
4233
+ };
4234
+ }
4235
+ async updateSearchEnvironment(input, _context) {
4236
+ const projectInfo = await this.provider.getProjectInfo();
4237
+ const result = await this.provider.updateSearchEnvironment({
4238
+ projectId: projectInfo.projectId,
4239
+ runtimeSlug: input.environmentSlug,
4240
+ ...input.name === void 0 ? {} : { name: input.name },
4241
+ ...input.status === void 0 ? {} : { status: input.status }
4242
+ });
4243
+ return {
4244
+ success: result.success,
4245
+ environment: result.runtime
4246
+ };
4247
+ }
4248
+ async deleteSearchEnvironment(environmentSlug, _context) {
4249
+ const projectInfo = await this.provider.getProjectInfo();
4250
+ return this.provider.deleteSearchEnvironment({
4251
+ projectId: projectInfo.projectId,
4252
+ runtimeSlug: environmentSlug
4253
+ });
4254
+ }
4255
+ async syncSearchEnvironment(environmentSlug, _context) {
4256
+ const normalizedSlug = normalizeEnvironmentSlug(environmentSlug);
4257
+ if (!normalizedSlug) {
4258
+ throw new Error("Search environment slug is required.");
4259
+ }
4260
+ const packageJsonPath = path14.join(this.targetProjectRoot, "package.json");
4261
+ const guidanceNotes = [
4262
+ `Run the command from ${this.targetProjectRoot}.`,
4263
+ "This tool returns guidance mode because Phase 13 keeps sync truthful to the real exported-project flow instead of pretending MCP generated a fresh payload itself."
4264
+ ];
4265
+ try {
4266
+ const packageJson = JSON.parse(
4267
+ await readFile8(packageJsonPath, "utf-8")
4268
+ );
4269
+ if (packageJson.scripts?.["search:sync"]) {
4270
+ return {
4271
+ success: true,
4272
+ mode: "guidance",
4273
+ environmentSlug: normalizedSlug,
4274
+ command: `pnpm search:sync --env ${normalizedSlug}`,
4275
+ workingDirectory: this.targetProjectRoot,
4276
+ jobId: null,
4277
+ status: null,
4278
+ notes: guidanceNotes
4279
+ };
4280
+ }
4281
+ } catch {
4282
+ guidanceNotes.push(
4283
+ `Package script lookup at ${packageJsonPath} was unavailable, so MCP is falling back to the package CLI command.`
4284
+ );
4285
+ }
4286
+ return {
4287
+ success: true,
4288
+ mode: "guidance",
4289
+ environmentSlug: normalizedSlug,
4290
+ command: `npx @primeuicom/cli search sync --env ${normalizedSlug}`,
4291
+ workingDirectory: this.targetProjectRoot,
4292
+ jobId: null,
4293
+ status: null,
4294
+ notes: guidanceNotes
4295
+ };
4296
+ }
4297
+ async listExports(_context) {
4298
+ await this.ensureTempLayout();
3476
4299
  return this.provider.listExports();
3477
4300
  }
3478
4301
  async createExport(_context) {
@@ -3489,6 +4312,20 @@ var ProjectSyncService = class {
3489
4312
  }
3490
4313
  };
3491
4314
  }
4315
+ async createComponentExport(componentId, _context) {
4316
+ await this.ensureTempLayout();
4317
+ const result = await this.provider.createComponentExport(componentId);
4318
+ const manifestPath = buildManifestPath(this.exportsRoot, result.export.id);
4319
+ await writeUtf8(manifestPath, `${JSON.stringify(result, null, 2)}
4320
+ `);
4321
+ return {
4322
+ ...result,
4323
+ guidance: {
4324
+ artifacts: [buildExportManifestArtifact(manifestPath)],
4325
+ requiredActions: `Call download_component_export with id "${result.export.id}" next. This is a component-track manifest; do not use page copy tools until a component registry copy tool is available.`
4326
+ }
4327
+ };
4328
+ }
3492
4329
  async downloadExportById(id, _context) {
3493
4330
  await this.ensureTempLayout();
3494
4331
  const exportsList = await this.provider.listExports();
@@ -3496,13 +4333,13 @@ var ProjectSyncService = class {
3496
4333
  if (!selected) {
3497
4334
  throw new Error(`Export not found: ${id}`);
3498
4335
  }
3499
- const targetZipPath = path13.join(this.exportsRoot, `${id}.zip`);
3500
- const targetProjectPath = path13.join(this.exportsRoot, id);
4336
+ const targetZipPath = path14.join(this.exportsRoot, `${id}.zip`);
4337
+ const targetProjectPath = path14.join(this.exportsRoot, id);
3501
4338
  const manifestPath = buildManifestPath(this.exportsRoot, id);
3502
4339
  let manifest;
3503
4340
  try {
3504
4341
  manifest = parsePrimeUiExportManifest(
3505
- JSON.parse(await readFile7(manifestPath, "utf-8"))
4342
+ JSON.parse(await readFile8(manifestPath, "utf-8"))
3506
4343
  );
3507
4344
  } catch (error) {
3508
4345
  const reason = error instanceof Error ? error.message : String(error);
@@ -3532,6 +4369,29 @@ var ProjectSyncService = class {
3532
4369
  }
3533
4370
  };
3534
4371
  }
4372
+ async downloadComponentExportById(id, _context) {
4373
+ await this.ensureTempLayout();
4374
+ const manifestPath = buildManifestPath(this.exportsRoot, id);
4375
+ const manifest = await this.readComponentExportManifest(id, manifestPath);
4376
+ const targetZipPath = path14.join(this.exportsRoot, `${id}.zip`);
4377
+ const targetProjectPath = path14.join(this.exportsRoot, id);
4378
+ await ensureDir(this.exportsRoot);
4379
+ await this.provider.downloadExportArchive(id, targetZipPath);
4380
+ await resetDir(targetProjectPath);
4381
+ await extractZip(targetZipPath, targetProjectPath);
4382
+ return {
4383
+ exportId: id,
4384
+ projectPath: targetProjectPath,
4385
+ manifestPath,
4386
+ guidance: {
4387
+ artifacts: [
4388
+ buildReferenceExportArtifact(targetProjectPath),
4389
+ buildExportManifestArtifact(manifestPath)
4390
+ ],
4391
+ requiredActions: `Use the component export_manifest artifact as the source of truth for component "${manifest.component.componentId}" and the reference_export artifact for inspection only. The next component-track step is a registry component copy tool; do not install the virtual page as a normal page.`
4392
+ }
4393
+ };
4394
+ }
3535
4395
  async inspectPage(slug, _context) {
3536
4396
  await this.ensureTempLayout();
3537
4397
  const pageDetails = await this.provider.getProjectPageBySlug(slug);
@@ -3543,6 +4403,25 @@ var ProjectSyncService = class {
3543
4403
  reportRows: reportPayload.reportRows
3544
4404
  };
3545
4405
  }
4406
+ async readComponentExportManifest(id, manifestPath) {
4407
+ let manifest;
4408
+ try {
4409
+ manifest = parsePrimeUiComponentExportManifest(
4410
+ JSON.parse(await readFile8(manifestPath, "utf-8"))
4411
+ );
4412
+ } catch (error) {
4413
+ const reason = error instanceof Error ? error.message : String(error);
4414
+ throw new Error(
4415
+ `Component export manifest is required for download id "${id}". Run create_component_export for this export before downloading. Details: ${reason}`
4416
+ );
4417
+ }
4418
+ if (manifest.export.id !== id || manifest.exportId !== id) {
4419
+ throw new Error(
4420
+ `Component export manifest mismatch for id "${id}". Run create_component_export and retry download.`
4421
+ );
4422
+ }
4423
+ return manifest;
4424
+ }
3546
4425
  async copyPage(originPageSlug, _context) {
3547
4426
  await this.ensureTempLayout();
3548
4427
  return copyPageFromExport({
@@ -3568,6 +4447,14 @@ var ProjectSyncService = class {
3568
4447
  pageDetails
3569
4448
  });
3570
4449
  }
4450
+ async copyRegistryComponent(componentId, _context) {
4451
+ await this.ensureTempLayout();
4452
+ return copyRegistryComponentFromExport({
4453
+ projectRoot: this.targetProjectRoot,
4454
+ exportsRoot: this.exportsRoot,
4455
+ componentId
4456
+ });
4457
+ }
3571
4458
  async copyExportable(exportableKey, _context) {
3572
4459
  await this.ensureTempLayout();
3573
4460
  return copyExportableFromExport({
@@ -3586,6 +4473,30 @@ var ProjectSyncService = class {
3586
4473
  await ensureDir(this.tempRoot);
3587
4474
  await ensureDir(this.exportsRoot);
3588
4475
  }
4476
+ getRelatedIndexesForRuntime(overview, runtime) {
4477
+ const indexes = [];
4478
+ const seen = /* @__PURE__ */ new Set();
4479
+ const pushIndex = (index) => {
4480
+ if (!index || seen.has(index.id)) {
4481
+ return;
4482
+ }
4483
+ seen.add(index.id);
4484
+ indexes.push(index);
4485
+ };
4486
+ if (overview.defaultIndex) {
4487
+ const matchesByUid = runtime.currentMeilisearchIndexUid && overview.defaultIndex.meilisearchIndexUid === runtime.currentMeilisearchIndexUid;
4488
+ const matchesDefaultSlug = runtime.slug === overview.runtimeModel.defaultRuntimeSlug && overview.defaultIndex.kind === "default-runtime";
4489
+ if (matchesByUid || matchesDefaultSlug) {
4490
+ pushIndex(overview.defaultIndex);
4491
+ }
4492
+ }
4493
+ for (const index of overview.customIndexes) {
4494
+ if (runtime.currentMeilisearchIndexUid && index.meilisearchIndexUid === runtime.currentMeilisearchIndexUid) {
4495
+ pushIndex(index);
4496
+ }
4497
+ }
4498
+ return indexes;
4499
+ }
3589
4500
  };
3590
4501
 
3591
4502
  // src/runtime.ts
@@ -3776,6 +4687,57 @@ var LazyProjectSyncSource = class {
3776
4687
  }
3777
4688
  );
3778
4689
  }
4690
+ async getSearchOverview(context) {
4691
+ return this.withService(
4692
+ context,
4693
+ (service) => service.getSearchOverview(context),
4694
+ {
4695
+ requireTargetProjectRoot: false
4696
+ }
4697
+ );
4698
+ }
4699
+ async getSearchEnvironment(environmentSlug, context) {
4700
+ return this.withService(
4701
+ context,
4702
+ (service) => service.getSearchEnvironment(environmentSlug, context),
4703
+ {
4704
+ requireTargetProjectRoot: false
4705
+ }
4706
+ );
4707
+ }
4708
+ async createSearchEnvironment(input, context) {
4709
+ return this.withMutationService(
4710
+ context,
4711
+ (service) => service.createSearchEnvironment(input, context),
4712
+ {
4713
+ requireTargetProjectRoot: false
4714
+ }
4715
+ );
4716
+ }
4717
+ async updateSearchEnvironment(input, context) {
4718
+ return this.withMutationService(
4719
+ context,
4720
+ (service) => service.updateSearchEnvironment(input, context),
4721
+ {
4722
+ requireTargetProjectRoot: false
4723
+ }
4724
+ );
4725
+ }
4726
+ async deleteSearchEnvironment(environmentSlug, context) {
4727
+ return this.withMutationService(
4728
+ context,
4729
+ (service) => service.deleteSearchEnvironment(environmentSlug, context),
4730
+ {
4731
+ requireTargetProjectRoot: false
4732
+ }
4733
+ );
4734
+ }
4735
+ async syncSearchEnvironment(environmentSlug, context) {
4736
+ return this.withService(
4737
+ context,
4738
+ (service) => service.syncSearchEnvironment(environmentSlug, context)
4739
+ );
4740
+ }
3779
4741
  async listExports(context) {
3780
4742
  return this.withService(context, (service) => service.listExports(context));
3781
4743
  }
@@ -3785,12 +4747,24 @@ var LazyProjectSyncSource = class {
3785
4747
  (service) => service.createExport(context)
3786
4748
  );
3787
4749
  }
4750
+ async createComponentExport(componentId, context) {
4751
+ return this.withService(
4752
+ context,
4753
+ (service) => service.createComponentExport(componentId, context)
4754
+ );
4755
+ }
3788
4756
  async downloadExportById(id, context) {
3789
4757
  return this.withService(
3790
4758
  context,
3791
4759
  (service) => service.downloadExportById(id, context)
3792
4760
  );
3793
4761
  }
4762
+ async downloadComponentExportById(id, context) {
4763
+ return this.withService(
4764
+ context,
4765
+ (service) => service.downloadComponentExportById(id, context)
4766
+ );
4767
+ }
3794
4768
  async inspectPage(slug, context) {
3795
4769
  const result = await this.withService(
3796
4770
  context,
@@ -3811,6 +4785,12 @@ var LazyProjectSyncSource = class {
3811
4785
  (service) => service.copyComponent(originPageSlug, blockId, componentId, context)
3812
4786
  );
3813
4787
  }
4788
+ async copyRegistryComponent(componentId, context) {
4789
+ return this.withMutationService(
4790
+ context,
4791
+ (service) => service.copyRegistryComponent(componentId, context)
4792
+ );
4793
+ }
3814
4794
  async copyExportable(exportableKey, context) {
3815
4795
  return this.withMutationService(
3816
4796
  context,
@@ -3911,6 +4891,18 @@ var exportPageSchema = z4.object({
3911
4891
  componentsPath: z4.string().describe("Page components directory path relative to export root."),
3912
4892
  manifest: exportPageManifestSchema
3913
4893
  });
4894
+ var componentExportComponentSchema = z4.object({
4895
+ componentId: z4.string().describe("PrimeUI component registry identifier used to create export."),
4896
+ name: z4.string().describe("Human-readable PrimeUI component name from registry metadata."),
4897
+ pageType: z4.string().describe("Page type used by the virtual component export snapshot."),
4898
+ family: z4.string().describe("Component family/group metadata from the PrimeUI registry."),
4899
+ defaultPropsAvailable: z4.boolean().describe("True when registry default props were available for export."),
4900
+ isReadyToExport: z4.boolean().describe("True when this component export payload is ready to download.")
4901
+ });
4902
+ var componentExportPageSchema = exportPageSchema.omit({
4903
+ pagePath: true,
4904
+ componentsPath: true
4905
+ });
3914
4906
  var dependencySectionSchema = z4.enum([
3915
4907
  "dependencies",
3916
4908
  "devDependencies",
@@ -3939,8 +4931,12 @@ var skippedCopyFileSchema = z4.object({
3939
4931
  targetPath: z4.string().describe(
3940
4932
  "Relative target path intentionally not copied into user project root."
3941
4933
  ),
3942
- reason: z4.enum(["package_json_managed_as_dependencies"]).describe(
3943
- "Machine-readable reason for skipping this file. package_json_managed_as_dependencies means package.json was handled as dependency guidance instead of direct file copy."
4934
+ reason: z4.enum([
4935
+ "package_json_managed_as_dependencies",
4936
+ "virtual_component_route",
4937
+ "not_component_dependency"
4938
+ ]).describe(
4939
+ "Machine-readable reason for skipping this file. package_json_managed_as_dependencies means package.json was handled as dependency guidance instead of direct file copy. virtual_component_route means the internal component-export route was intentionally not installed into the target app. not_component_dependency means the manifest file belongs to page/template context outside the selected registry component dependency set."
3944
4940
  )
3945
4941
  });
3946
4942
  var runtimeGuidanceArtifactSchema = z4.object({
@@ -4024,7 +5020,7 @@ WORKFLOW ORDER (always follow this sequence):
4024
5020
  4. inspect_page -> inspect selected page components and produce a structured comparison table
4025
5021
  5. create_export -> generate export snapshot and local manifest with page file lists + shared exportables
4026
5022
  6. download_export -> download to temp directory
4027
- 7. copy_page, copy_component, or copy_exportable -> transfer one selected page, one selected block-level component, or one selected shared exportable safely
5023
+ 7. copy_page, copy_component, copy_exportable, or copy_registry_component -> transfer one selected page, one selected block-level page component, one selected shared exportable, or one registry component safely
4028
5024
  8. Reconcile integration points, dependency follow-up, and reported conflicts
4029
5025
  `.trim();
4030
5026
  var initialInstructions = `
@@ -4064,7 +5060,7 @@ CRITICAL RULES FOR PAGE IMPORT:
4064
5060
  - copy_page for page manifests,
4065
5061
  - copy_component for one selected block-level component instance,
4066
5062
  - copy_exportable for shared exportables.
4067
- - Always call copy_page, copy_component, or copy_exportable instead of manual file copy.
5063
+ - Always call copy_page, copy_component, copy_exportable, or copy_registry_component instead of manual file copy.
4068
5064
  - copy_page performs safe copy only:
4069
5065
  - new files are copied,
4070
5066
  - identical files are reported,
@@ -4252,6 +5248,59 @@ ${WORKFLOW_SUMMARY}`,
4252
5248
  openWorldHint: true
4253
5249
  }
4254
5250
  };
5251
+ var toolCreateComponentExport = {
5252
+ title: "PrimeUI Create Component Export",
5253
+ description: `Create a component-track export for one known PrimeUI componentId and wait for completion. This uses the component registry export API and returns a component-aware sidecar manifest plus the virtual page manifest created by Studio.
5254
+
5255
+ WHEN TO USE: Use this only for the component-registry import track when the user wants to export a single known componentId. This is separate from create_export, which exports selected project pages.
5256
+
5257
+ AFTER CALLING:
5258
+ - Verify component.componentId matches the requested componentId.
5259
+ - Verify component.isReadyToExport is true and page.manifest.files is present.
5260
+ - Local component sidecar manifest is saved to .primeui/temp/exports/[exportId].manifest.json.
5261
+ - Use the returned export ID to call download_component_export.
5262
+ - Use copy_registry_component after download_component_export for this component-track manifest. Do not use page copy tools for component-track manifests.
5263
+ - If guidance is present in the result, read guidance.artifacts and follow guidance.requiredActions before continuing.
5264
+
5265
+ ${WORKFLOW_SUMMARY}`,
5266
+ inputSchema: {
5267
+ projectRoot: projectRootInputSchema,
5268
+ componentId: z4.string().min(1).describe("PrimeUI component registry identifier to export.")
5269
+ },
5270
+ outputSchema: z4.object({
5271
+ exportId: z4.string().describe(
5272
+ "Freshly created component export identifier. Use this as download_component_export input.id."
5273
+ ),
5274
+ export: z4.object({
5275
+ id: z4.string().describe("Created export identifier."),
5276
+ status: exportStatusSchema,
5277
+ createdAt: z4.string().describe("Export creation timestamp in ISO-8601 UTC format."),
5278
+ expiresAt: z4.string().nullable().describe(
5279
+ "Export expiration timestamp in ISO-8601 UTC format, or null when export has no explicit expiration."
5280
+ ),
5281
+ summary: exportSummarySchema.describe(
5282
+ "Export run summary with total/successful/failed counters."
5283
+ ),
5284
+ exportables: z4.array(exportableSchema).describe("Shared exportables included in this export payload.")
5285
+ }).describe("Created component export summary."),
5286
+ component: componentExportComponentSchema,
5287
+ page: componentExportPageSchema.describe(
5288
+ "Virtual page manifest for this component export."
5289
+ ),
5290
+ pages: z4.array(componentExportPageSchema).describe(
5291
+ "Page-compatible virtual page payload associated with this component export."
5292
+ ),
5293
+ guidance: runtimeGuidanceSchema.optional().describe(
5294
+ "Mandatory runtime guidance for local artifacts created during component export."
5295
+ )
5296
+ }),
5297
+ annotations: {
5298
+ readOnlyHint: false,
5299
+ destructiveHint: false,
5300
+ idempotentHint: false,
5301
+ openWorldHint: true
5302
+ }
5303
+ };
4255
5304
  var toolDownloadExport = {
4256
5305
  title: "PrimeUI Download Export",
4257
5306
  description: `Download a completed export into .primeui/temp/exports/[exportId]. Downloads and extracts the full export as a standalone Next.js project into the temp directory. This does NOT modify the user's project - files land only in .primeui/temp/.
@@ -4280,25 +5329,67 @@ AFTER DOWNLOAD:
4280
5329
  - Do not force cleanup at flow end; keep downloaded export files available for validation and follow-up checks.
4281
5330
  - If guidance is present in the result, read guidance.artifacts and follow guidance.requiredActions before choosing the next copy tool.
4282
5331
 
4283
- ${WORKFLOW_SUMMARY}`,
5332
+ ${WORKFLOW_SUMMARY}`,
5333
+ inputSchema: {
5334
+ projectRoot: projectRootInputSchema,
5335
+ id: z4.string().describe(
5336
+ "Export identifier to download. Prefer export.id from create_export; use list_exports only on explicit user request."
5337
+ )
5338
+ },
5339
+ outputSchema: z4.object({
5340
+ exportId: z4.string().describe(
5341
+ "Downloaded export identifier. Should match the requested input.id for traceability."
5342
+ ),
5343
+ projectPath: z4.string().describe(
5344
+ "Absolute local path to extracted export root in .primeui/temp/exports/[exportId]. Read files from here only."
5345
+ ),
5346
+ manifestPath: z4.string().describe(
5347
+ "Absolute path to sidecar export manifest file (.primeui/temp/exports/[exportId].manifest.json) saved by create_export and required by copy_page and copy_component."
5348
+ ),
5349
+ guidance: runtimeGuidanceSchema.optional().describe(
5350
+ "Mandatory runtime guidance for the downloaded export and manifest artifacts. Present only on successful tool results."
5351
+ )
5352
+ }),
5353
+ annotations: {
5354
+ readOnlyHint: false,
5355
+ destructiveHint: false,
5356
+ idempotentHint: true,
5357
+ openWorldHint: true
5358
+ }
5359
+ };
5360
+ var toolDownloadComponentExport = {
5361
+ title: "PrimeUI Download Component Export",
5362
+ description: `Download a completed component-track export into .primeui/temp/exports/[exportId]. Downloads and extracts the full export archive through the existing PrimeUI export download endpoint, but requires a local component sidecar manifest created by create_component_export.
5363
+
5364
+ Do NOT call this as the first step. Requires export ID from create_component_export.
5365
+
5366
+ WHEN TO USE: Call this AFTER create_component_export has returned a completed component export. This does NOT modify the user's project - files land only in .primeui/temp/.
5367
+
5368
+ NOTE:
5369
+ - Download of an export ID without a local component sidecar manifest will fail.
5370
+ - A normal page export manifest from create_export is not accepted here.
5371
+ - The next component-track step is copy_registry_component. Do not use page copy tools for component-track manifests.
5372
+ - If guidance is present in the result, read guidance.artifacts and follow guidance.requiredActions before continuing.
5373
+
5374
+ ${WORKFLOW_SUMMARY}`,
4284
5375
  inputSchema: {
4285
5376
  projectRoot: projectRootInputSchema,
4286
5377
  id: z4.string().describe(
4287
- "Export identifier to download. Prefer export.id from create_export; use list_exports only on explicit user request."
5378
+ "Component export identifier to download. Use export.id from create_component_export."
4288
5379
  )
4289
5380
  },
4290
5381
  outputSchema: z4.object({
4291
5382
  exportId: z4.string().describe(
4292
- "Downloaded export identifier. Should match the requested input.id for traceability."
5383
+ "Downloaded component export identifier. Should match the requested input.id."
4293
5384
  ),
4294
5385
  projectPath: z4.string().describe(
4295
5386
  "Absolute local path to extracted export root in .primeui/temp/exports/[exportId]. Read files from here only."
4296
5387
  ),
4297
5388
  manifestPath: z4.string().describe(
4298
- "Absolute path to sidecar export manifest file (.primeui/temp/exports/[exportId].manifest.json) saved by create_export and required by copy_page and copy_component."
5389
+ "Absolute path to component sidecar export manifest saved by create_component_export."
4299
5390
  ),
4300
5391
  guidance: runtimeGuidanceSchema.optional().describe(
4301
- "Mandatory runtime guidance for the downloaded export and manifest artifacts. Present only on successful tool results."
5392
+ "Mandatory runtime guidance for the downloaded component export and manifest artifacts."
4302
5393
  )
4303
5394
  }),
4304
5395
  annotations: {
@@ -4491,6 +5582,97 @@ ${WORKFLOW_SUMMARY}`,
4491
5582
  openWorldHint: false
4492
5583
  }
4493
5584
  };
5585
+ var toolCopyRegistryComponent = {
5586
+ title: "PrimeUI Copy Registry Component",
5587
+ description: `Safely copy one registry component from a downloaded component export into the user's local project. Works only with component-track files in .primeui/temp/exports and does NOT call PrimeUI API.
5588
+
5589
+ WHEN TO USE:
5590
+ - Call this AFTER create_component_export and download_component_export.
5591
+ - Use this for component-registry exports, not page exports.
5592
+ - Pass componentId from the create_component_export result so the local component sidecar manifest can be validated before copying.
5593
+
5594
+ BEHAVIOR:
5595
+ - Reads the component sidecar manifest saved by create_component_export.
5596
+ - Validates that manifest.component.componentId matches input.componentId.
5597
+ - Copies files strictly from page.manifest.files in the component sidecar manifest.
5598
+ - Skips virtual route files that include __primeui-component-export, because those are reference/insertion hints and must not be installed as normal app routes.
5599
+ - Never copies package.json directly. package.json is used only to add missing dependency entries and report dependency version conflicts.
5600
+ - Preserves export-relative paths for copied files in this first version.
5601
+ - Never overwrites existing conflicting files.
5602
+ - Writes full conflict details to .primeui/temp/exports/[exportId].copy-registry-component-report-[copyId].json.
5603
+ - Reports copied files, identical files, conflicts, skipped files, dependency additions, dependency version conflicts, missing manifest files, and manual insertion guidance.
5604
+ - If status is needs_review, resolve conflicts, missing manifest files, or dependency version conflicts before treating transfer as complete.
5605
+
5606
+ ${WORKFLOW_SUMMARY}`,
5607
+ inputSchema: {
5608
+ projectRoot: projectRootInputSchema,
5609
+ componentId: z4.string().describe(
5610
+ "PrimeUI component registry identifier from create_component_export output. Must match the local component sidecar manifest."
5611
+ )
5612
+ },
5613
+ outputSchema: z4.object({
5614
+ status: z4.enum(["completed", "needs_review"]).describe(
5615
+ "Decision state for next step. needs_review means conflicts, dependency version conflicts, missing manifest files, or no copyable files require manual review."
5616
+ ),
5617
+ message: z4.string().describe(
5618
+ "Decision-oriented summary with reportPath and manual insertion guidance."
5619
+ ),
5620
+ reportPath: z4.string().describe(
5621
+ "Absolute path to saved local report with conflicts, skipped files, and component manifest metadata."
5622
+ ),
5623
+ exportId: z4.string().describe("Resolved local component export identifier used for copy."),
5624
+ exportPath: z4.string().describe("Absolute path to local extracted component export root."),
5625
+ manifestPath: z4.string().describe(
5626
+ "Absolute path to the local component sidecar manifest used during copy."
5627
+ ),
5628
+ component: componentExportComponentSchema.describe(
5629
+ "Component metadata from the validated component sidecar manifest."
5630
+ ),
5631
+ manifestFiles: z4.array(z4.string()).describe(
5632
+ "Normalized page.manifest.files from the component sidecar manifest."
5633
+ ),
5634
+ copyableFiles: z4.array(z4.string()).describe(
5635
+ "Manifest files considered for copying after filtering virtual route files and package.json."
5636
+ ),
5637
+ newFiles: z4.array(z4.string()).describe("Relative target paths for new files copied."),
5638
+ identicalFiles: z4.array(z4.string()).describe("Relative target paths for existing byte-identical files."),
5639
+ conflictFiles: z4.array(conflictFileSchema).describe(
5640
+ "Files that already exist and differ from export version. Never overwritten."
5641
+ ),
5642
+ skippedFiles: z4.array(skippedCopyFileSchema).describe(
5643
+ "Manifest files intentionally not copied, such as package.json or virtual component-export routes."
5644
+ ),
5645
+ addedDependencies: z4.array(dependencyToAddSchema).describe(
5646
+ "Dependencies that were missing and have been added to user's package.json."
5647
+ ),
5648
+ dependenciesVersionConflicts: z4.array(dependencyVersionConflictSchema).describe(
5649
+ "Dependencies with version mismatch between export and user project. Report only."
5650
+ ),
5651
+ missingManifestFiles: z4.array(z4.string()).describe(
5652
+ "Manifest file paths that were expected but missing from the downloaded export."
5653
+ ),
5654
+ summary: z4.object({
5655
+ totalManifestFiles: z4.number(),
5656
+ totalCopyableFiles: z4.number(),
5657
+ copiedFiles: z4.number(),
5658
+ identicalFiles: z4.number(),
5659
+ conflictFiles: z4.number(),
5660
+ skippedFiles: z4.number(),
5661
+ addedDependencies: z4.number(),
5662
+ dependenciesVersionConflicts: z4.number(),
5663
+ missingManifestFiles: z4.number()
5664
+ }),
5665
+ guidance: runtimeGuidanceSchema.describe(
5666
+ "Structured follow-up guidance. It always instructs manual insertion into a real target page and warns that the virtual route was skipped."
5667
+ )
5668
+ }),
5669
+ annotations: {
5670
+ readOnlyHint: false,
5671
+ destructiveHint: false,
5672
+ idempotentHint: false,
5673
+ openWorldHint: false
5674
+ }
5675
+ };
4494
5676
  var toolCopyExportable = {
4495
5677
  title: "PrimeUI Copy Exportable",
4496
5678
  description: `Safely copy one shared exportable from downloaded export into the user's local project. Works only with local files in .primeui/temp/exports and does NOT call PrimeUI API.
@@ -4767,6 +5949,124 @@ var projectIssueReportSubmitInputSchema = z4.object({
4767
5949
  "Optional issue report tags. Empty values are trimmed and dropped by the API."
4768
5950
  )
4769
5951
  });
5952
+ var searchEnvironmentSlugSchema = z4.string().describe(
5953
+ "Search environment slug, for example 'prod', 'staging', or a custom environment slug."
5954
+ );
5955
+ var searchRuntimeStatusSchema = z4.enum([
5956
+ "bootstrapping",
5957
+ "active",
5958
+ "indexing",
5959
+ "failed",
5960
+ "inactive"
5961
+ ]);
5962
+ var searchRuntimeSchema = z4.object({
5963
+ createdAt: z4.string().describe("ISO timestamp when the environment was created."),
5964
+ currentMeilisearchIndexUid: z4.string().nullable().describe(
5965
+ "Current Meilisearch index UID bound to this environment, when available."
5966
+ ),
5967
+ currentQueryId: z4.string().nullable().describe(
5968
+ "Current query credential or query binding identifier, when available."
5969
+ ),
5970
+ id: z4.string().describe("Stable internal environment record identifier."),
5971
+ lastErrorSummary: z4.string().nullable().describe("Most recent error summary for this environment, if any."),
5972
+ lastFailedSyncAt: z4.string().nullable().describe("ISO timestamp of the last failed sync for this environment."),
5973
+ lastSuccessfulSyncAt: z4.string().nullable().describe(
5974
+ "ISO timestamp of the last successful sync for this environment."
5975
+ ),
5976
+ name: z4.string().describe("Human-readable environment name."),
5977
+ slug: z4.string().describe("Canonical search environment slug."),
5978
+ status: searchRuntimeStatusSchema.describe(
5979
+ "Current environment lifecycle status."
5980
+ ),
5981
+ updatedAt: z4.string().describe("ISO timestamp of the latest environment update.")
5982
+ });
5983
+ var searchOverviewOutputSchema = z4.object({
5984
+ success: z4.literal(true),
5985
+ projectId: z4.string().describe("PrimeUI project identifier for this overview."),
5986
+ runtimeModel: z4.object({
5987
+ additionalRuntimesSupported: z4.literal(true),
5988
+ defaultRuntimeAutoWired: z4.literal(true),
5989
+ defaultRuntimeSlug: z4.literal("prod"),
5990
+ mode: z4.literal("runtime-first"),
5991
+ panelCompatibility: z4.literal("disabled"),
5992
+ stagingRuntimeAutoWired: z4.literal(false),
5993
+ stagingRuntimeSlug: z4.literal("staging")
5994
+ }).describe("Managed-search runtime model summary from the PrimeUI API."),
5995
+ search: z4.object({
5996
+ bootstrapCompletedAt: z4.string().nullable(),
5997
+ createdAt: z4.string().nullable(),
5998
+ id: z4.string().nullable(),
5999
+ enabled: z4.boolean(),
6000
+ status: z4.enum(["inactive", "active", "degraded"]),
6001
+ defaultIndexId: z4.string().nullable(),
6002
+ defaultSearchId: z4.string().nullable(),
6003
+ lastErrorSummary: z4.string().nullable(),
6004
+ lastFailedSyncAt: z4.string().nullable(),
6005
+ lastSuccessfulSyncAt: z4.string().nullable(),
6006
+ updatedAt: z4.string().nullable()
6007
+ }).describe("Top-level managed-search root status."),
6008
+ runtimes: z4.array(searchRuntimeSchema).describe("All configured search environments for this project."),
6009
+ defaultIndex: z4.record(z4.unknown()).nullable().describe(
6010
+ "Default index payload from the API overview, or null when absent."
6011
+ ),
6012
+ customIndexes: z4.array(z4.record(z4.unknown())).describe("Additional search index payloads from the API overview."),
6013
+ recentJobs: z4.array(z4.record(z4.unknown())).describe("Recent search jobs from the overview API."),
6014
+ recentSyncRuns: z4.array(z4.record(z4.unknown())).describe("Recent sync-run payloads from the overview API."),
6015
+ sources: z4.array(z4.record(z4.unknown())).describe("Configured managed-search sources from the overview API."),
6016
+ lastError: z4.record(z4.unknown()).nullable().describe("Latest overview-level managed-search error payload, if any."),
6017
+ queryProtection: z4.record(z4.unknown()).describe("Query protection summary from the overview API."),
6018
+ relevanceSettings: z4.record(z4.unknown()).describe("Relevance settings summary from the overview API.")
6019
+ });
6020
+ var searchEnvironmentOutputSchema = z4.object({
6021
+ success: z4.literal(true),
6022
+ environmentSlug: z4.string().describe("Resolved search environment slug for this focused MCP view."),
6023
+ environment: searchRuntimeSchema.describe("Selected environment record."),
6024
+ primaryIndex: z4.record(z4.unknown()).nullable().describe(
6025
+ "Primary related index for this environment when one can be identified."
6026
+ ),
6027
+ relatedIndexes: z4.array(z4.record(z4.unknown())).describe("Related search indexes inferred for this environment."),
6028
+ recentJobs: z4.array(z4.record(z4.unknown())).describe(
6029
+ "Recent jobs filtered to the related indexes for this environment."
6030
+ ),
6031
+ recentSyncRuns: z4.array(z4.record(z4.unknown())).describe(
6032
+ "Recent sync runs filtered to the related indexes for this environment."
6033
+ ),
6034
+ search: z4.record(z4.unknown()).describe(
6035
+ "Top-level managed-search root status carried through from the overview API."
6036
+ ),
6037
+ runtimeModel: z4.record(z4.unknown()).describe(
6038
+ "Managed-search runtime model carried through from the overview API."
6039
+ ),
6040
+ sources: z4.array(z4.record(z4.unknown())).describe("Managed-search sources carried through from the overview API."),
6041
+ lastError: z4.record(z4.unknown()).nullable().describe("Latest overview-level managed-search error payload, if any.")
6042
+ });
6043
+ var searchEnvironmentMutationOutputSchema = z4.object({
6044
+ success: z4.literal(true),
6045
+ environment: searchRuntimeSchema.describe(
6046
+ "Environment payload returned by the PrimeUI API."
6047
+ )
6048
+ });
6049
+ var searchEnvironmentDeleteOutputSchema = z4.object({
6050
+ success: z4.literal(true)
6051
+ });
6052
+ var searchEnvironmentSyncOutputSchema = z4.object({
6053
+ success: z4.literal(true),
6054
+ mode: z4.enum(["executed", "guidance"]).describe(
6055
+ "Whether MCP executed the real sync command or returned next-step guidance."
6056
+ ),
6057
+ environmentSlug: z4.string().describe("Resolved search environment slug."),
6058
+ command: z4.string().describe(
6059
+ "Exact command the agent should run or that MCP already executed."
6060
+ ),
6061
+ workingDirectory: z4.string().describe("Absolute project directory where the command applies."),
6062
+ jobId: z4.string().nullable().describe(
6063
+ "Search job identifier when the command was actually executed and returned one."
6064
+ ),
6065
+ status: z4.string().nullable().describe("Execution status when available; null for guidance-only mode."),
6066
+ notes: z4.array(z4.string()).describe(
6067
+ "Actionable notes that explain why guidance or execution was chosen."
6068
+ )
6069
+ });
4770
6070
  var toolProjectDescriptionGet = {
4771
6071
  title: "PrimeUI Project Description Get",
4772
6072
  description: `Atomic external API helper. Returns the current shared project description for the scoped PrimeUI project.
@@ -4974,6 +6274,139 @@ AFTER CALLING:
4974
6274
  openWorldHint: true
4975
6275
  }
4976
6276
  };
6277
+ var toolSearchOverviewGet = {
6278
+ title: "PrimeUI Search Overview Get",
6279
+ description: `Standalone managed-search helper. Returns the current search overview for the scoped PrimeUI project using the existing environment-first API contract.
6280
+
6281
+ WHEN TO USE:
6282
+ - Use this as the starting point for MCP search work.
6283
+ - This tool is intentionally separate from the page/export workflow chain.
6284
+ - Call this before focused environment inspection or environment mutations when the current search state is not already known.
6285
+
6286
+ AFTER CALLING:
6287
+ - Use runtimes as the authoritative inventory of search environments.
6288
+ - Use search_environment_get when the caller wants one environment-focused view instead of the full overview payload.`,
6289
+ inputSchema: optionalProjectRootInputObjectSchema,
6290
+ outputSchema: searchOverviewOutputSchema,
6291
+ annotations: {
6292
+ readOnlyHint: true,
6293
+ destructiveHint: false,
6294
+ idempotentHint: true,
6295
+ openWorldHint: true
6296
+ }
6297
+ };
6298
+ var toolSearchEnvironmentGet = {
6299
+ title: "PrimeUI Search Environment Get",
6300
+ description: `Standalone managed-search helper. Returns one environment-focused view derived from the existing search overview contract.
6301
+
6302
+ WHEN TO USE:
6303
+ - Use this when the caller already knows the target environment slug.
6304
+ - This tool does not rely on a separate runtime-details endpoint; it is an MCP convenience projection over the overview API.
6305
+
6306
+ AFTER CALLING:
6307
+ - Treat environment as the source of truth for the selected search environment.
6308
+ - Treat relatedIndexes, recentJobs, and recentSyncRuns as MCP-filtered convenience data for this one environment.`,
6309
+ inputSchema: {
6310
+ projectRoot: projectRootInputSchema,
6311
+ environmentSlug: searchEnvironmentSlugSchema
6312
+ },
6313
+ outputSchema: searchEnvironmentOutputSchema,
6314
+ annotations: {
6315
+ readOnlyHint: true,
6316
+ destructiveHint: false,
6317
+ idempotentHint: true,
6318
+ openWorldHint: true
6319
+ }
6320
+ };
6321
+ var toolSearchEnvironmentCreate = {
6322
+ title: "PrimeUI Search Environment Create",
6323
+ description: `Standalone managed-search helper. Creates one new search environment through the existing PrimeUI search-environment management API.
6324
+
6325
+ WHEN TO USE:
6326
+ - Use this only when the caller explicitly wants to create a new search environment.
6327
+ - This is a power-user environment management tool, not part of the primary page/export workflow.
6328
+
6329
+ AFTER CALLING:
6330
+ - Treat the returned environment payload as the immediate API result for the new environment.`,
6331
+ inputSchema: {
6332
+ projectRoot: projectRootInputSchema,
6333
+ slug: searchEnvironmentSlugSchema,
6334
+ name: z4.string().describe("Human-readable environment name to create.")
6335
+ },
6336
+ outputSchema: searchEnvironmentMutationOutputSchema,
6337
+ annotations: {
6338
+ readOnlyHint: false,
6339
+ destructiveHint: false,
6340
+ idempotentHint: false,
6341
+ openWorldHint: true
6342
+ }
6343
+ };
6344
+ var toolSearchEnvironmentUpdate = {
6345
+ title: "PrimeUI Search Environment Update",
6346
+ description: `Standalone managed-search helper. Updates one existing search environment through the PrimeUI search-environment management API.
6347
+
6348
+ WHEN TO USE:
6349
+ - Use this only when the caller explicitly wants to update an existing search environment.
6350
+ - Keep this narrow: name and status updates only.
6351
+
6352
+ AFTER CALLING:
6353
+ - Treat the returned environment payload as the immediate API result for the updated environment.`,
6354
+ inputSchema: {
6355
+ projectRoot: projectRootInputSchema,
6356
+ environmentSlug: searchEnvironmentSlugSchema,
6357
+ name: z4.string().optional().describe("Optional new human-readable environment name."),
6358
+ status: searchRuntimeStatusSchema.optional().describe("Optional new environment lifecycle status.")
6359
+ },
6360
+ outputSchema: searchEnvironmentMutationOutputSchema,
6361
+ annotations: {
6362
+ readOnlyHint: false,
6363
+ destructiveHint: false,
6364
+ idempotentHint: false,
6365
+ openWorldHint: true
6366
+ }
6367
+ };
6368
+ var toolSearchEnvironmentDelete = {
6369
+ title: "PrimeUI Search Environment Delete",
6370
+ description: `Standalone managed-search helper. Deletes one search environment through the PrimeUI search-environment management API when the backend allows it.
6371
+
6372
+ WHEN TO USE:
6373
+ - Use this only when the caller explicitly wants to delete an existing environment.
6374
+ - This tool relies on normal API allow/deny behavior instead of inventing separate MCP policy summaries.`,
6375
+ inputSchema: {
6376
+ projectRoot: projectRootInputSchema,
6377
+ environmentSlug: searchEnvironmentSlugSchema
6378
+ },
6379
+ outputSchema: searchEnvironmentDeleteOutputSchema,
6380
+ annotations: {
6381
+ readOnlyHint: false,
6382
+ destructiveHint: true,
6383
+ idempotentHint: false,
6384
+ openWorldHint: true
6385
+ }
6386
+ };
6387
+ var toolSearchEnvironmentSync = {
6388
+ title: "PrimeUI Search Environment Sync",
6389
+ description: `Standalone managed-search helper. Returns the real search sync command context for one environment and may execute it only when MCP can do so truthfully.
6390
+
6391
+ WHEN TO USE:
6392
+ - Use this when the caller wants to sync one search environment against the actual local exported-project flow.
6393
+ - This tool intentionally avoids pretending that a runtime-action API wrapper would always represent fresh local project state.
6394
+
6395
+ AFTER CALLING:
6396
+ - If mode is guidance, run the returned command from workingDirectory next.
6397
+ - If mode is executed, treat jobId and status as the immediate sync invocation result.`,
6398
+ inputSchema: {
6399
+ projectRoot: projectRootInputSchema,
6400
+ environmentSlug: searchEnvironmentSlugSchema
6401
+ },
6402
+ outputSchema: searchEnvironmentSyncOutputSchema,
6403
+ annotations: {
6404
+ readOnlyHint: false,
6405
+ destructiveHint: false,
6406
+ idempotentHint: false,
6407
+ openWorldHint: true
6408
+ }
6409
+ };
4977
6410
 
4978
6411
  // src/server.ts
4979
6412
  var ZERO_ARG_PROJECT_ROOT_TOOLS = /* @__PURE__ */ new Set([
@@ -4982,7 +6415,8 @@ var ZERO_ARG_PROJECT_ROOT_TOOLS = /* @__PURE__ */ new Set([
4982
6415
  "project_pages_list",
4983
6416
  "list_exports",
4984
6417
  "create_export",
4985
- "clear_temp"
6418
+ "clear_temp",
6419
+ "search_overview_get"
4986
6420
  ]);
4987
6421
  function serializeToolData(data) {
4988
6422
  try {
@@ -5260,6 +6694,20 @@ function createPrimeUiMcpServer(source) {
5260
6694
  }
5261
6695
  }
5262
6696
  );
6697
+ server.registerTool(
6698
+ "create_component_export",
6699
+ toolCreateComponentExport,
6700
+ async ({ componentId, projectRoot }) => {
6701
+ try {
6702
+ const result = await source.createComponentExport(componentId, {
6703
+ projectRoot
6704
+ });
6705
+ return okResult("create_component_export", result);
6706
+ } catch (error) {
6707
+ return errorResult(error);
6708
+ }
6709
+ }
6710
+ );
5263
6711
  server.registerTool(
5264
6712
  "download_export",
5265
6713
  toolDownloadExport,
@@ -5275,6 +6723,20 @@ function createPrimeUiMcpServer(source) {
5275
6723
  }
5276
6724
  }
5277
6725
  );
6726
+ server.registerTool(
6727
+ "download_component_export",
6728
+ toolDownloadComponentExport,
6729
+ async ({ id, projectRoot }) => {
6730
+ try {
6731
+ const result = await source.downloadComponentExportById(id, {
6732
+ projectRoot
6733
+ });
6734
+ return okResult("download_component_export", result);
6735
+ } catch (error) {
6736
+ return errorResult(error);
6737
+ }
6738
+ }
6739
+ );
5278
6740
  server.registerTool(
5279
6741
  "clear_temp",
5280
6742
  toolClearTemp,
@@ -5327,6 +6789,20 @@ function createPrimeUiMcpServer(source) {
5327
6789
  }
5328
6790
  }
5329
6791
  );
6792
+ server.registerTool(
6793
+ "copy_registry_component",
6794
+ toolCopyRegistryComponent,
6795
+ async ({ componentId, projectRoot }) => {
6796
+ try {
6797
+ const result = await source.copyRegistryComponent(componentId, {
6798
+ projectRoot
6799
+ });
6800
+ return okResult("copy_registry_component", result);
6801
+ } catch (error) {
6802
+ return errorResult(error);
6803
+ }
6804
+ }
6805
+ );
5330
6806
  server.registerTool(
5331
6807
  "copy_exportable",
5332
6808
  toolCopyExportable,
@@ -5344,6 +6820,99 @@ function createPrimeUiMcpServer(source) {
5344
6820
  }
5345
6821
  }
5346
6822
  );
6823
+ server.registerTool(
6824
+ "search_overview_get",
6825
+ toolSearchOverviewGet,
6826
+ async (args) => {
6827
+ const { projectRoot } = args ?? {};
6828
+ try {
6829
+ const result = await source.getSearchOverview({ projectRoot });
6830
+ return okResult("search_overview_get", result);
6831
+ } catch (error) {
6832
+ return errorResult(error);
6833
+ }
6834
+ }
6835
+ );
6836
+ server.registerTool(
6837
+ "search_environment_get",
6838
+ toolSearchEnvironmentGet,
6839
+ async ({ environmentSlug, projectRoot }) => {
6840
+ try {
6841
+ const result = await source.getSearchEnvironment(environmentSlug, { projectRoot });
6842
+ return okResult("search_environment_get", result);
6843
+ } catch (error) {
6844
+ return errorResult(error);
6845
+ }
6846
+ }
6847
+ );
6848
+ server.registerTool(
6849
+ "search_environment_create",
6850
+ toolSearchEnvironmentCreate,
6851
+ async ({ name, projectRoot, slug }) => {
6852
+ try {
6853
+ const result = await source.createSearchEnvironment(
6854
+ {
6855
+ name,
6856
+ slug
6857
+ },
6858
+ { projectRoot }
6859
+ );
6860
+ return okResult("search_environment_create", result);
6861
+ } catch (error) {
6862
+ return errorResult(error);
6863
+ }
6864
+ }
6865
+ );
6866
+ server.registerTool(
6867
+ "search_environment_update",
6868
+ toolSearchEnvironmentUpdate,
6869
+ async ({
6870
+ environmentSlug,
6871
+ name,
6872
+ projectRoot,
6873
+ status
6874
+ }) => {
6875
+ try {
6876
+ const result = await source.updateSearchEnvironment(
6877
+ {
6878
+ environmentSlug,
6879
+ ...name === void 0 ? {} : { name },
6880
+ ...status === void 0 ? {} : { status }
6881
+ },
6882
+ { projectRoot }
6883
+ );
6884
+ return okResult("search_environment_update", result);
6885
+ } catch (error) {
6886
+ return errorResult(error);
6887
+ }
6888
+ }
6889
+ );
6890
+ server.registerTool(
6891
+ "search_environment_delete",
6892
+ toolSearchEnvironmentDelete,
6893
+ async ({ environmentSlug, projectRoot }) => {
6894
+ try {
6895
+ const result = await source.deleteSearchEnvironment(environmentSlug, {
6896
+ projectRoot
6897
+ });
6898
+ return okResult("search_environment_delete", result);
6899
+ } catch (error) {
6900
+ return errorResult(error);
6901
+ }
6902
+ }
6903
+ );
6904
+ server.registerTool(
6905
+ "search_environment_sync",
6906
+ toolSearchEnvironmentSync,
6907
+ async ({ environmentSlug, projectRoot }) => {
6908
+ try {
6909
+ const result = await source.syncSearchEnvironment(environmentSlug, { projectRoot });
6910
+ return okResult("search_environment_sync", result);
6911
+ } catch (error) {
6912
+ return errorResult(error);
6913
+ }
6914
+ }
6915
+ );
5347
6916
  return server;
5348
6917
  }
5349
6918