ply-ui-mcp 0.1.30 → 0.1.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -116,7 +116,7 @@ Metadata always. Free source only when `includeSource` is true. Pro source is ne
116
116
  { "names": ["button", "card"], "cwd": "/path/to/your-app" }
117
117
  ```
118
118
 
119
- Runs `ply-ui-cli add --yes`. Pro names need `PLY_LICENSE_KEY` on the MCP process (or `licenseKey` on the tool).
119
+ Runs `ply-ui-cli add --yes`. Pro names need `PLY_LICENSE_KEY` on the MCP process (or `licenseKey` on the tool). The result includes `missingPackages` and, when something is missing, `installCommand`. `overwrite: true` asks the host to confirm before any file is replaced.
120
120
 
121
121
  ### `init_project`
122
122
 
@@ -124,7 +124,7 @@ Runs `ply-ui-cli add --yes`. Pro names need `PLY_LICENSE_KEY` on the MCP process
124
124
  { "cwd": "/path/to/your-app" }
125
125
  ```
126
126
 
127
- Runs `ply-ui-cli init --yes`. Writes `ply-ui.json`, styles, icons, and editor rules when those files are missing.
127
+ Runs `ply-ui-cli init --yes`. Writes `ply-ui.json`, styles, icons, the Cursor rule, snippets, and the UI design skill at `.cursor/skills/ply-ui-design/` and `.agents/skills/ply-ui-design/` when those files are missing. `refreshEditorKit: true` replaces a kit that is already there.
128
128
 
129
129
  ### `doctor`
130
130
 
@@ -132,7 +132,7 @@ Runs `ply-ui-cli init --yes`. Writes `ply-ui.json`, styles, icons, and editor ru
132
132
  { "cwd": "/path/to/your-app" }
133
133
  ```
134
134
 
135
- Read-only. `isError` is set when `ply-ui-cli doctor` exits non-zero.
135
+ Read-only. The result lists each check. `isError` is set when `ply-ui-cli doctor` exits non-zero.
136
136
 
137
137
  ### `diff_components`
138
138
 
@@ -148,7 +148,7 @@ Omit `names` (or pass `[]`) to diff every tracked component. Read-only.
148
148
  { "names": ["card"], "cwd": "/path/to/your-app", "force": false, "overwriteLocal": false, "merge": false }
149
149
  ```
150
150
 
151
- Runs `ply-ui-cli update --yes`. `force` takes upstream on conflicts. `merge` applies a 3-way merge. `overwriteLocal` reverts files you edited that upstream did not change.
151
+ Runs `ply-ui-cli update --yes`. The result lists one row per file. `force` takes upstream on conflicts. `merge` applies a 3-way merge. `overwriteLocal` reverts files you edited that upstream did not change. `force` or `overwriteLocal` asks the host to confirm before replace.
152
152
 
153
153
  ## Resources
154
154
 
@@ -197,10 +197,10 @@ Run npx ply-ui-cli doctor. It checks ply-ui.json, the Angular workspace, @angula
197
197
  Open Theme Studio at https://ply-ui.com/theme/ or the docs customizer, pick a preset or hue, then copy the Tailwind v4 @theme block into src/tailwind.css. ply-ui.css points --ply-primary and Tailwind blue-* utilities at that palette (--ply-brand and --ply-scale-*). The live preview shows buttons, tabs, forms, and overlays together.
198
198
 
199
199
  **Can AI agents install Ply?**
200
- Yes. npx -y ply-ui-mcp runs over stdio in Cursor, VS Code, Claude Code, Claude Desktop, Codex, Antigravity, Grok Build, Kimi Code, Qwen Code, Windsurf, and other local hosts. ChatGPT and Gemini chat apps use the Streamable HTTP connector at https://mcp.ply-ui.com/mcp (catalog tools) or a local npx -y ply-ui-mcp --http without --read-only so add/init/update can see the project. Pro add uses PLY_LICENSE_KEY on the MCP process. Setup for each host: https://ply-ui.com/getting-started/#ai-agents-mcp. Editors that skip MCP can copy the Cursor rule and snippet pack from https://ply-ui.com/getting-started/#editor-rules.
200
+ Yes. npx -y ply-ui-mcp runs over stdio in Cursor, VS Code, Claude Code, Claude Desktop, Codex, Antigravity, Grok Build, Kimi Code, Qwen Code, Windsurf, and other local hosts. ChatGPT and Gemini chat apps use the Streamable HTTP connector at https://mcp.ply-ui.com/mcp (catalog tools) or a local npx -y ply-ui-mcp --http without --read-only so add/init/update can see the project. doctor, add_components, and update_components return structuredContent: checks, missing packages with the install command, and one result per file. Hosts that can ask confirm an overwrite before replace. init_project accepts refreshEditorKit. When PLY_LICENSE_KEY is already set, leave it in the environment and out of the tool call. Setup for each host: https://ply-ui.com/getting-started/#ai-agents-mcp. Editors that skip MCP can copy the Cursor rule and snippet pack from https://ply-ui.com/getting-started/#editor-rules.
201
201
 
202
202
  **What does init install for AI agents?**
203
- npx ply-ui-cli init writes ply-ui.json, ply-ui.css, icon sprites, .cursor/rules/ply-ui.mdc, .vscode/ply-ui.code-snippets, and the UI design skill at .cursor/skills/ply-ui-design/ (SKILL.md, reference.md, examples.md) when those files are missing. The skill tells the agent to reuse ply-button, ply-card, and ply-input-group, keep one accent, and include loading, error, empty, and data states. It does not install components. Published copy: https://ply-ui.com/docs/ai/skills/ply-ui-design/SKILL.md. Walkthrough: https://ply-ui.com/learn/ply-ui-design-skill/.
203
+ npx ply-ui-cli init writes ply-ui.json, ply-ui.css, icon sprites, .cursor/rules/ply-ui.mdc, .vscode/ply-ui.code-snippets, and the UI design skill at .cursor/skills/ply-ui-design/ and .agents/skills/ply-ui-design/ (SKILL.md, reference.md, examples.md) when those files are missing. npx ply-ui-cli init --refresh-editor-kit replaces a kit that is already there. The skill tells the agent to reuse ply-button, ply-card, and ply-input-group, keep one accent, and include loading, error, empty, and data states. It does not install components. Published copy: https://ply-ui.com/docs/ai/skills/ply-ui-design/SKILL.md. Walkthrough: https://ply-ui.com/learn/ply-ui-design-skill/.
204
204
 
205
205
  **Do AI agents use fewer tokens with Ply?**
206
206
  Usually, yes. With Ply the agent copies a finished component (CLI or MCP) and wires it, instead of generating a toolbar, selection model, sanitizer, and SSR guards from a blank file. Token use still depends on the prompt and the model. A reconstructed Claude/Grok session for the rich text editor is at https://ply-ui.com/learn/ai-agent-tokens-rich-text-editor/ — that is a teaching simulation, not a lab benchmark.
package/dist/index.js CHANGED
@@ -350,18 +350,28 @@ function installHint(name) {
350
350
  }
351
351
 
352
352
  // src/result.ts
353
+ function asRecord(data) {
354
+ if (data && typeof data === "object" && !Array.isArray(data)) {
355
+ return data;
356
+ }
357
+ return void 0;
358
+ }
353
359
  function okJson(data) {
360
+ const structuredContent = asRecord(data);
354
361
  return {
355
- content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
362
+ content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
363
+ ...structuredContent ? { structuredContent } : {}
356
364
  };
357
365
  }
358
366
  function failJson(message, extra = {}) {
367
+ const structuredContent = { ok: false, error: message, ...extra };
359
368
  return {
360
369
  isError: true,
370
+ structuredContent,
361
371
  content: [
362
372
  {
363
373
  type: "text",
364
- text: JSON.stringify({ ok: false, error: message, ...extra }, null, 2)
374
+ text: JSON.stringify(structuredContent, null, 2)
365
375
  }
366
376
  ]
367
377
  };
@@ -582,7 +592,7 @@ async function searchComponents(args) {
582
592
  // package.json
583
593
  var package_default = {
584
594
  name: "ply-ui-mcp",
585
- version: "0.1.30",
595
+ version: "0.1.32",
586
596
  description: "Ply MCP server \u2014 stdio or Streamable HTTP (--http). List, search, init, doctor, diff, update, and add Angular + Tailwind components (Pro with PLY_LICENSE_KEY). Not MUI Base UI.",
587
597
  type: "commonjs",
588
598
  main: "dist/index.js",
@@ -644,7 +654,7 @@ var package_default = {
644
654
  esbuild: "0.28.2",
645
655
  "fast-uri": "3.1.8",
646
656
  "proxy-addr": "2.0.8",
647
- hono: "4.13.7",
657
+ hono: "4.13.13",
648
658
  qs: "6.16.0"
649
659
  }
650
660
  };
@@ -653,6 +663,7 @@ var package_default = {
653
663
  var PACKAGE_VERSION = package_default.version;
654
664
 
655
665
  // src/catalog.ts
666
+ var SERVER_INSTRUCTIONS = "Search the catalog before inventing a component name. The hosted catalog cannot write files. A local install is init_project, then add_components. When PLY_LICENSE_KEY is already set, leave it in the environment and out of the tool call.";
656
667
  var catalogAnnotations = {
657
668
  readOnlyHint: true,
658
669
  destructiveHint: false,
@@ -660,10 +671,13 @@ var catalogAnnotations = {
660
671
  openWorldHint: true
661
672
  };
662
673
  function createCatalogMcpServer() {
663
- const server = new import_mcp2.McpServer({
664
- name: MCP_SERVER_NAME,
665
- version: PACKAGE_VERSION
666
- });
674
+ const server = new import_mcp2.McpServer(
675
+ {
676
+ name: MCP_SERVER_NAME,
677
+ version: PACKAGE_VERSION
678
+ },
679
+ { instructions: SERVER_INSTRUCTIONS }
680
+ );
667
681
  server.registerTool(
668
682
  "list_components",
669
683
  {
@@ -698,8 +712,44 @@ function createCatalogMcpServer() {
698
712
  return server;
699
713
  }
700
714
 
715
+ // src/elicit.ts
716
+ async function confirmReplace(server, message) {
717
+ try {
718
+ const result = await server.server.elicitInput({
719
+ mode: "form",
720
+ message,
721
+ requestedSchema: {
722
+ type: "object",
723
+ properties: {
724
+ replace: {
725
+ type: "boolean",
726
+ title: "Replace existing files",
727
+ description: "Overwrite the copies already in the project.",
728
+ default: false
729
+ }
730
+ },
731
+ required: ["replace"]
732
+ }
733
+ });
734
+ if (result.action === "accept" && result.content?.replace === true) return "replace";
735
+ return "keep";
736
+ } catch (err) {
737
+ const text = err instanceof Error ? err.message : String(err);
738
+ if (text.includes("does not support form elicitation")) return "unsupported";
739
+ throw err;
740
+ }
741
+ }
742
+ async function resolveReplace(requested, confirm, message) {
743
+ if (!requested) return { apply: false };
744
+ if (!confirm) return { apply: true };
745
+ const decision = await confirm(message);
746
+ if (decision === "keep") return { apply: false, confirmation: "declined" };
747
+ if (decision === "unsupported") return { apply: true, confirmation: "unsupported" };
748
+ return { apply: true, confirmation: "accepted" };
749
+ }
750
+
701
751
  // src/tools/add-components.ts
702
- var import_zod5 = require("zod");
752
+ var import_zod6 = require("zod");
703
753
 
704
754
  // src/cli.ts
705
755
  var import_fs = __toESM(require("fs"));
@@ -775,18 +825,96 @@ function resolveProjectCwd(cwd) {
775
825
  return import_path.default.resolve(root);
776
826
  }
777
827
 
828
+ // src/cli-report.ts
829
+ var import_zod5 = require("zod");
830
+ var STATUS = {
831
+ "\u2714": "ok",
832
+ "\u26A0": "warn",
833
+ "\u2716": "error"
834
+ };
835
+ var FILE_ACTION = {
836
+ "\u2191": "updated",
837
+ "+": "added",
838
+ "\u2193": "reverted",
839
+ "=": "kept",
840
+ "\u22C8": "merged",
841
+ "\u26A0": "merge-conflict",
842
+ "\u21C4": "saved-aside"
843
+ };
844
+ var doctorOutput = import_zod5.z.looseObject({
845
+ ok: import_zod5.z.boolean(),
846
+ checks: import_zod5.z.array(
847
+ import_zod5.z.looseObject({
848
+ name: import_zod5.z.string(),
849
+ status: import_zod5.z.enum(["ok", "warn", "error"]),
850
+ message: import_zod5.z.string()
851
+ })
852
+ )
853
+ });
854
+ var addOutput = import_zod5.z.looseObject({
855
+ ok: import_zod5.z.boolean(),
856
+ missingPackages: import_zod5.z.array(import_zod5.z.string()),
857
+ installCommand: import_zod5.z.string().optional()
858
+ });
859
+ var updateOutput = import_zod5.z.looseObject({
860
+ ok: import_zod5.z.boolean(),
861
+ files: import_zod5.z.array(
862
+ import_zod5.z.looseObject({
863
+ path: import_zod5.z.string(),
864
+ action: import_zod5.z.enum(["updated", "added", "reverted", "kept", "merged", "merge-conflict", "saved-aside"]),
865
+ detail: import_zod5.z.string().optional()
866
+ })
867
+ )
868
+ });
869
+ function plain(text) {
870
+ return text.replace(/\u001b\[[0-9;]*m/g, "").replace(/\r\n/g, "\n");
871
+ }
872
+ function parseDoctorChecks(stdout) {
873
+ const checks = [];
874
+ for (const line of plain(stdout).split("\n")) {
875
+ const match = line.match(/^([✔⚠✖])\s+([^:]+):\s*(.*)$/);
876
+ if (!match) continue;
877
+ const status = STATUS[match[1]];
878
+ if (!status) continue;
879
+ checks.push({ name: match[2].trim(), status, message: match[3].trim() });
880
+ }
881
+ return checks;
882
+ }
883
+ function parseAddReport(stdout) {
884
+ const match = plain(stdout).match(/Install missing npm dependenc(?:y|ies):\n\s+(.+)/);
885
+ if (!match) return { missingPackages: [] };
886
+ const installCommand = match[1].trim();
887
+ const packages = installCommand.match(/^(?:npm install|pnpm add|yarn add|bun add)\s+(.+)$/);
888
+ return {
889
+ installCommand,
890
+ missingPackages: packages ? packages[1].split(/\s+/).filter(Boolean) : []
891
+ };
892
+ }
893
+ function parseUpdateFiles(stdout) {
894
+ const files = [];
895
+ for (const line of plain(stdout).split("\n")) {
896
+ const match = line.match(/^\s*([↑+↓=⋈⚠⇄])\s+(\S+)(?:\s+\((.*)\))?\s*$/);
897
+ if (!match) continue;
898
+ const action = FILE_ACTION[match[1]];
899
+ if (!action) continue;
900
+ const detail = match[3]?.trim();
901
+ files.push(detail ? { path: match[2], action, detail } : { path: match[2], action });
902
+ }
903
+ return files;
904
+ }
905
+
778
906
  // src/tools/add-components.ts
779
907
  var addComponentsInput = {
780
- names: import_zod5.z.array(import_zod5.z.string().min(1)).min(1).describe("One or more registry component names to install (aliases like sheet \u2192 drawer are resolved)"),
781
- cwd: import_zod5.z.string().optional().describe(
908
+ names: import_zod6.z.array(import_zod6.z.string().min(1)).min(1).describe("One or more registry component names to install (aliases like sheet \u2192 drawer are resolved)"),
909
+ cwd: import_zod6.z.string().optional().describe(
782
910
  "Project root containing ply-ui.json (defaults to MCP process cwd / PLY_CWD / BASE_UI_CWD)"
783
911
  ),
784
- overwrite: import_zod5.z.boolean().optional().default(false).describe("Overwrite existing component folders (maps to CLI --overwrite)"),
785
- licenseKey: import_zod5.z.string().optional().describe(
912
+ overwrite: import_zod6.z.boolean().optional().default(false).describe("Overwrite existing component folders (maps to CLI --overwrite)"),
913
+ licenseKey: import_zod6.z.string().optional().describe(
786
914
  "Ply Pro license. Prefer PLY_LICENSE_KEY (or BASE_UI_LICENSE_KEY) in the MCP server env instead of putting a key in chat."
787
915
  )
788
916
  };
789
- async function addComponents(args) {
917
+ async function addComponents(args, hooks = {}) {
790
918
  try {
791
919
  const cwd = resolveProjectCwd(args.cwd);
792
920
  const names = [
@@ -868,19 +996,33 @@ async function addComponents(args) {
868
996
  );
869
997
  }
870
998
  const toInstall = [...free, ...pro];
999
+ const replace = await resolveReplace(
1000
+ Boolean(args.overwrite),
1001
+ hooks.confirmReplace,
1002
+ `Replace existing files for ${toInstall.join(", ")}? This overwrites the copies already in the project.`
1003
+ );
871
1004
  const cliArgs = ["add", ...toInstall, "--yes"];
872
- if (args.overwrite) cliArgs.push("--overwrite");
1005
+ if (replace.apply) cliArgs.push("--overwrite");
873
1006
  const result = await runCli(cliArgs, {
874
1007
  cwd,
875
1008
  env: licenseKey ? { PLY_LICENSE_KEY: licenseKey, BASE_UI_LICENSE_KEY: licenseKey } : void 0
876
1009
  });
1010
+ const stdout = result.stdout.trim();
1011
+ const install = parseAddReport(stdout);
1012
+ const note = [
1013
+ `Files were written by ${CLI_BIN} (canonical installer). MCP does not replace the CLI.`,
1014
+ replace.confirmation === "declined" ? "Overwrite was not confirmed. Existing files were left in place." : ""
1015
+ ].filter(Boolean).join(" ");
877
1016
  if (!result.ok) {
878
1017
  return failJson(`${CLI_BIN} add failed.`, {
879
1018
  cwd,
880
1019
  names: toInstall,
881
1020
  exitCode: result.code,
882
- stdout: result.stdout.trim(),
1021
+ stdout,
883
1022
  stderr: result.stderr.trim(),
1023
+ missingPackages: install.missingPackages,
1024
+ ...install.installCommand ? { installCommand: install.installCommand } : {},
1025
+ ...replace.confirmation ? { confirmation: replace.confirmation } : {},
884
1026
  hint: `Ensure the project was initialized (${CLI_NPX} init --yes). CLI remains the canonical install path.`
885
1027
  });
886
1028
  }
@@ -889,9 +1031,12 @@ async function addComponents(args) {
889
1031
  cwd,
890
1032
  installed: toInstall,
891
1033
  cli: `${CLI_BIN} add --yes`,
892
- stdout: result.stdout.trim(),
1034
+ stdout,
893
1035
  stderr: result.stderr.trim() || void 0,
894
- note: `Files were written by ${CLI_BIN} (canonical installer). MCP does not replace the CLI.`
1036
+ missingPackages: install.missingPackages,
1037
+ ...install.installCommand ? { installCommand: install.installCommand } : {},
1038
+ ...replace.confirmation ? { confirmation: replace.confirmation } : {},
1039
+ note
895
1040
  });
896
1041
  } catch (err) {
897
1042
  return failJson(err.message || String(err));
@@ -899,12 +1044,12 @@ async function addComponents(args) {
899
1044
  }
900
1045
 
901
1046
  // src/tools/diff-components.ts
902
- var import_zod6 = require("zod");
1047
+ var import_zod7 = require("zod");
903
1048
  var diffComponentsInput = {
904
- names: import_zod6.z.array(import_zod6.z.string().min(1)).optional().describe(
1049
+ names: import_zod7.z.array(import_zod7.z.string().min(1)).optional().describe(
905
1050
  "Tracked component names to diff. Omit or pass [] to check every component in ply-ui-lock.json."
906
1051
  ),
907
- cwd: import_zod6.z.string().optional().describe(
1052
+ cwd: import_zod7.z.string().optional().describe(
908
1053
  "Project root containing ply-ui.json (defaults to MCP process cwd / PLY_CWD)"
909
1054
  )
910
1055
  };
@@ -944,9 +1089,9 @@ async function diffComponents(args = {}) {
944
1089
  }
945
1090
 
946
1091
  // src/tools/doctor.ts
947
- var import_zod7 = require("zod");
1092
+ var import_zod8 = require("zod");
948
1093
  var doctorInput = {
949
- cwd: import_zod7.z.string().optional().describe(
1094
+ cwd: import_zod8.z.string().optional().describe(
950
1095
  "Project root containing ply-ui.json (defaults to MCP process cwd / PLY_CWD). Read-only."
951
1096
  )
952
1097
  };
@@ -954,12 +1099,14 @@ async function doctor(args = {}) {
954
1099
  try {
955
1100
  const cwd = resolveProjectCwd(args.cwd);
956
1101
  const result = await runCli(["doctor"], { cwd });
1102
+ const stdout = result.stdout.trim();
957
1103
  const body = {
958
1104
  cwd,
959
1105
  cli: `${CLI_BIN} doctor`,
960
1106
  exitCode: result.code,
961
- stdout: result.stdout.trim(),
962
- stderr: result.stderr.trim() || void 0
1107
+ stdout,
1108
+ stderr: result.stderr.trim() || void 0,
1109
+ checks: parseDoctorChecks(stdout)
963
1110
  };
964
1111
  if (!result.ok) {
965
1112
  return failJson(`${CLI_BIN} doctor reported problems.`, body);
@@ -971,16 +1118,21 @@ async function doctor(args = {}) {
971
1118
  }
972
1119
 
973
1120
  // src/tools/init-project.ts
974
- var import_zod8 = require("zod");
1121
+ var import_zod9 = require("zod");
975
1122
  var initProjectInput = {
976
- cwd: import_zod8.z.string().optional().describe(
1123
+ cwd: import_zod9.z.string().optional().describe(
977
1124
  "Project root to initialize (defaults to MCP process cwd / PLY_CWD). Always non-interactive (`init --yes`)."
1125
+ ),
1126
+ refreshEditorKit: import_zod9.z.boolean().optional().default(false).describe(
1127
+ "Replace an editor kit that is already there (Cursor rule, snippets, and the design skill in .cursor/skills and .agents/skills). Maps to `init --refresh-editor-kit`."
978
1128
  )
979
1129
  };
980
1130
  async function initProject(args = {}) {
981
1131
  try {
982
1132
  const cwd = resolveProjectCwd(args.cwd);
983
- const result = await runCli(["init", "--yes"], { cwd });
1133
+ const cliArgs = ["init", "--yes"];
1134
+ if (args.refreshEditorKit) cliArgs.push("--refresh-editor-kit");
1135
+ const result = await runCli(cliArgs, { cwd });
984
1136
  if (!result.ok) {
985
1137
  return failJson(`${CLI_BIN} init failed.`, {
986
1138
  cwd,
@@ -993,7 +1145,7 @@ async function initProject(args = {}) {
993
1145
  return okJson({
994
1146
  ok: true,
995
1147
  cwd,
996
- cli: `${CLI_BIN} init --yes`,
1148
+ cli: [CLI_BIN, ...cliArgs].join(" "),
997
1149
  stdout: result.stdout.trim(),
998
1150
  stderr: result.stderr.trim() || void 0
999
1151
  });
@@ -1003,25 +1155,25 @@ async function initProject(args = {}) {
1003
1155
  }
1004
1156
 
1005
1157
  // src/tools/update-components.ts
1006
- var import_zod9 = require("zod");
1158
+ var import_zod10 = require("zod");
1007
1159
  var updateComponentsInput = {
1008
- names: import_zod9.z.array(import_zod9.z.string().min(1)).optional().describe(
1160
+ names: import_zod10.z.array(import_zod10.z.string().min(1)).optional().describe(
1009
1161
  "Tracked component names to update. Omit or pass [] to update every component in ply-ui-lock.json."
1010
1162
  ),
1011
- cwd: import_zod9.z.string().optional().describe(
1163
+ cwd: import_zod10.z.string().optional().describe(
1012
1164
  "Project root containing ply-ui.json (defaults to MCP process cwd / PLY_CWD)"
1013
1165
  ),
1014
- force: import_zod9.z.boolean().optional().default(false).describe(
1166
+ force: import_zod10.z.boolean().optional().default(false).describe(
1015
1167
  "On conflict (both local and upstream changed), take the upstream version. Does not revert local-only edits."
1016
1168
  ),
1017
- overwriteLocal: import_zod9.z.boolean().optional().default(false).describe(
1169
+ overwriteLocal: import_zod10.z.boolean().optional().default(false).describe(
1018
1170
  "Also revert files you edited that upstream did not change (`--overwrite-local`). Default skips those files."
1019
1171
  ),
1020
- merge: import_zod9.z.boolean().optional().default(false).describe(
1172
+ merge: import_zod10.z.boolean().optional().default(false).describe(
1021
1173
  "On conflict, apply a 3-way merge using the installed snapshot (`--merge`). force still wins."
1022
1174
  )
1023
1175
  };
1024
- async function updateComponents(args = {}) {
1176
+ async function updateComponents(args = {}, hooks = {}) {
1025
1177
  try {
1026
1178
  const cwd = resolveProjectCwd(args.cwd);
1027
1179
  const names = (args.names ?? []).map((n) => n.trim()).filter(Boolean);
@@ -1030,18 +1182,32 @@ async function updateComponents(args = {}) {
1030
1182
  return failJson(`Invalid component name: '${name}'.`);
1031
1183
  }
1032
1184
  }
1185
+ const target = names.length ? names.join(", ") : "tracked components";
1186
+ const replace = await resolveReplace(
1187
+ Boolean(args.force || args.overwriteLocal),
1188
+ hooks.confirmReplace,
1189
+ `Replace local files while updating ${target}? This overwrites copies already in the project.`
1190
+ );
1033
1191
  const cliArgs = ["update", ...names, "--yes"];
1034
- if (args.force) cliArgs.push("--force");
1035
- if (args.overwriteLocal) cliArgs.push("--overwrite-local");
1192
+ if (args.force && replace.apply) cliArgs.push("--force");
1193
+ if (args.overwriteLocal && replace.apply) cliArgs.push("--overwrite-local");
1036
1194
  if (args.merge) cliArgs.push("--merge");
1037
1195
  const result = await runCli(cliArgs, { cwd });
1196
+ const stdout = result.stdout.trim();
1197
+ const files = parseUpdateFiles(stdout);
1198
+ const note = [
1199
+ `Files were written by ${CLI_BIN} (canonical updater). MCP does not replace the CLI.`,
1200
+ replace.confirmation === "declined" ? "Replace was not confirmed. Conflicts and local-only edits were left in place." : ""
1201
+ ].filter(Boolean).join(" ");
1038
1202
  if (!result.ok) {
1039
1203
  return failJson(`${CLI_BIN} update failed.`, {
1040
1204
  cwd,
1041
1205
  names,
1042
1206
  exitCode: result.code,
1043
- stdout: result.stdout.trim(),
1207
+ stdout,
1044
1208
  stderr: result.stderr.trim(),
1209
+ files,
1210
+ ...replace.confirmation ? { confirmation: replace.confirmation } : {},
1045
1211
  hint: "Run diff_components first. Conflicts need --force; local-only edits need overwriteLocal."
1046
1212
  });
1047
1213
  }
@@ -1049,13 +1215,15 @@ async function updateComponents(args = {}) {
1049
1215
  ok: true,
1050
1216
  cwd,
1051
1217
  names: names.length ? names : "all-tracked",
1052
- force: Boolean(args.force),
1053
- overwriteLocal: Boolean(args.overwriteLocal),
1218
+ force: Boolean(args.force && replace.apply),
1219
+ overwriteLocal: Boolean(args.overwriteLocal && replace.apply),
1054
1220
  merge: Boolean(args.merge),
1055
1221
  cli: [CLI_BIN, ...cliArgs].join(" "),
1056
- stdout: result.stdout.trim(),
1222
+ stdout,
1057
1223
  stderr: result.stderr.trim() || void 0,
1058
- note: `Files were written by ${CLI_BIN} (canonical updater). MCP does not replace the CLI.`
1224
+ files,
1225
+ ...replace.confirmation ? { confirmation: replace.confirmation } : {},
1226
+ note
1059
1227
  });
1060
1228
  } catch (err) {
1061
1229
  return failJson(err.message || String(err));
@@ -1083,17 +1251,20 @@ function createMcpServer(options = {}) {
1083
1251
  "add_components",
1084
1252
  {
1085
1253
  title: "Add Ply components",
1086
- description: `Install registry components by shelling to \`${CLI_BIN} add --yes\`. --yes leaves an existing component in place; pass overwrite to replace it. Pro names require PLY_LICENSE_KEY (or licenseKey). Project must already have ply-ui.json.`,
1254
+ description: `Install registry components by shelling to \`${CLI_BIN} add --yes\`. --yes leaves an existing component in place; pass overwrite to replace it. Hosts that can ask confirm that overwrite first. Pro names require PLY_LICENSE_KEY (or licenseKey). Project must already have ply-ui.json. structuredContent includes missingPackages and installCommand.`,
1087
1255
  inputSchema: addComponentsInput,
1256
+ outputSchema: addOutput,
1088
1257
  annotations: writeAnnotations
1089
1258
  },
1090
- async (args) => addComponents(args)
1259
+ async (args) => addComponents(args, {
1260
+ confirmReplace: (message) => confirmReplace(server, message)
1261
+ })
1091
1262
  );
1092
1263
  server.registerTool(
1093
1264
  "init_project",
1094
1265
  {
1095
1266
  title: "Initialize Ply in a project",
1096
- description: `Run \`${CLI_BIN} init --yes\` in the target directory. Writes ply-ui.json, ply-ui.css, and icon sprites only when those files are missing, discovers the stylesheet already listed in angular.json, and inserts @source when it is absent. Always non-interactive.`,
1267
+ description: `Run \`${CLI_BIN} init --yes\` in the target directory. Writes ply-ui.json, ply-ui.css, and icon sprites only when those files are missing, discovers the stylesheet already listed in angular.json, and inserts @source when it is absent. Writes the design skill to .cursor/skills and .agents/skills when those files are missing. Pass refreshEditorKit to replace an existing editor kit. Always non-interactive.`,
1097
1268
  inputSchema: initProjectInput,
1098
1269
  annotations: writeAnnotations
1099
1270
  },
@@ -1103,8 +1274,9 @@ function createMcpServer(options = {}) {
1103
1274
  "doctor",
1104
1275
  {
1105
1276
  title: "Verify Ply project setup",
1106
- description: `Run \`${CLI_BIN} doctor\` (read-only). Returns isError when the CLI exits non-zero.`,
1277
+ description: `Run \`${CLI_BIN} doctor\` (read-only). structuredContent.checks lists each \u2714/\u26A0/\u2716 line. Returns isError when the CLI exits non-zero.`,
1107
1278
  inputSchema: doctorInput,
1279
+ outputSchema: doctorOutput,
1108
1280
  annotations: readOnlyAnnotations
1109
1281
  },
1110
1282
  async (args) => doctor(args)
@@ -1123,11 +1295,14 @@ function createMcpServer(options = {}) {
1123
1295
  "update_components",
1124
1296
  {
1125
1297
  title: "Update installed Ply components",
1126
- description: `Run \`${CLI_BIN} update --yes\`. Untouched files take upstream. Conflicts stay local and the CLI exits non-zero unless force or merge. Local-only edits skip unless overwriteLocal.`,
1298
+ description: `Run \`${CLI_BIN} update --yes\`. Untouched files take upstream. Conflicts stay local and the CLI exits non-zero unless force or merge. Local-only edits skip unless overwriteLocal. Hosts that can ask confirm force and overwriteLocal before those flags replace files. structuredContent.files is one result per file line.`,
1127
1299
  inputSchema: updateComponentsInput,
1300
+ outputSchema: updateOutput,
1128
1301
  annotations: writeAnnotations
1129
1302
  },
1130
- async (args) => updateComponents(args)
1303
+ async (args) => updateComponents(args, {
1304
+ confirmReplace: (message) => confirmReplace(server, message)
1305
+ })
1131
1306
  );
1132
1307
  }
1133
1308
  return server;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/catalog.ts","../src/resources.ts","../src/registry.ts","../src/utf8.ts","../src/tools/get-component.ts","../src/brand.ts","../src/install-hint.ts","../src/result.ts","../src/tools/list-components.ts","../src/tools/search-components.ts","../src/aliases.ts","../package.json","../src/version.ts","../src/tools/add-components.ts","../src/cli.ts","../src/tools/diff-components.ts","../src/tools/doctor.ts","../src/tools/init-project.ts","../src/tools/update-components.ts","../src/server.ts","../src/http.ts","../src/auth-metadata.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * ply-ui-mcp — MCP server wrapping the Ply registry + CLI.\n *\n * Default: stdio (Cursor, Claude Code/Desktop, Kimi, VS Code, Windsurf).\n * `--http`: Streamable HTTP for ChatGPT / Gemini chat apps and remote MCP URLs.\n * Hosted HTTP should use `--read-only` so catalog tools work without a local project.\n */\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { createMcpServer, PACKAGE_VERSION } from './server';\nimport { startHttpServer } from './http';\nimport { MCP_PACKAGE } from './brand';\n\nfunction parseArgs(argv: string[]): {\n http: boolean;\n readOnly: boolean;\n port: number;\n host: string;\n} {\n let http =\n argv.includes('--http') ||\n process.env.PLY_MCP_HTTP === '1' ||\n process.env.BASE_UI_MCP_HTTP === '1';\n let readOnly =\n argv.includes('--read-only') ||\n process.env.PLY_MCP_READ_ONLY === '1' ||\n process.env.BASE_UI_MCP_READ_ONLY === '1';\n let port = Number(process.env.PORT || process.env.PLY_MCP_PORT || process.env.BASE_UI_MCP_PORT || 3334);\n let host = process.env.PLY_MCP_HOST || process.env.BASE_UI_MCP_HOST || (http ? '127.0.0.1' : '127.0.0.1');\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg === '--port' && argv[i + 1]) {\n port = Number(argv[++i]);\n } else if (arg?.startsWith('--port=')) {\n port = Number(arg.slice('--port='.length));\n } else if (arg === '--host' && argv[i + 1]) {\n host = argv[++i]!;\n } else if (arg?.startsWith('--host=')) {\n host = arg.slice('--host='.length);\n }\n }\n if (!Number.isFinite(port) || port <= 0) port = 3334;\n return { http, readOnly, port, host };\n}\n\nasync function main() {\n const opts = parseArgs(process.argv.slice(2));\n if (opts.http) {\n startHttpServer({\n host: opts.host,\n port: opts.port,\n readOnly: opts.readOnly,\n authToken:\n process.env.PLY_MCP_AUTH_TOKEN?.trim() ||\n process.env.BASE_UI_MCP_AUTH_TOKEN?.trim() ||\n undefined,\n });\n return;\n }\n\n const server = createMcpServer({ mutating: true });\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error(`${MCP_PACKAGE} v${PACKAGE_VERSION} ready on stdio`);\n}\n\nmain().catch((err) => {\n console.error(`${MCP_PACKAGE} failed to start:`, err);\n process.exit(1);\n});\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { registerResources } from './resources';\nimport { getComponent, getComponentInput } from './tools/get-component';\nimport { listComponents, listComponentsInput } from './tools/list-components';\nimport { searchComponents, searchComponentsInput } from './tools/search-components';\nimport { PACKAGE_VERSION } from './version';\nimport { CLI_NPX, MCP_SERVER_NAME } from './brand';\n\n/** ChatGPT treats tools as writes unless readOnlyHint is set. */\nconst catalogAnnotations = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n} as const;\n\n/** Catalog-only server: safe to bundle on Cloudflare Workers (no child_process). */\nexport function createCatalogMcpServer(): McpServer {\n const server = new McpServer({\n name: MCP_SERVER_NAME,\n version: PACKAGE_VERSION,\n });\n\n server.registerTool(\n 'list_components',\n {\n title: 'List Ply components',\n description:\n `List components from the Ply registry. Filter by tier (free|pro|all), category, or name substring. Does not install anything. To copy a component into a project, tell the user to run ${CLI_NPX} add <name>.`,\n inputSchema: listComponentsInput,\n annotations: catalogAnnotations,\n },\n async (args) => listComponents(args)\n );\n\n server.registerTool(\n 'get_component',\n {\n title: 'Get component details',\n description:\n `Get registry metadata for one component (deps, category, file list). Free source only when includeSource=true. Pro source is never streamed via MCP. Does not install; returns installCommand (${CLI_NPX} add <name>).`,\n inputSchema: getComponentInput,\n annotations: catalogAnnotations,\n },\n async (args) => getComponent(args)\n );\n\n server.registerTool(\n 'search_components',\n {\n title: 'Search Ply components',\n description:\n `Fuzzy / token search over registry component names (e.g. \"dialog\", \"sheet\", \"carousel\"). Does not install anything. Prefer this before guessing names, then give the user ${CLI_NPX} add <name> (or local stdio add_components).`,\n inputSchema: searchComponentsInput,\n annotations: catalogAnnotations,\n },\n async (args) => searchComponents(args)\n );\n\n registerResources(server);\n return server;\n}\n","import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport {\n SITE_URL,\n fetchFreeItem,\n fetchIndex,\n fetchText,\n isSafeItemName,\n} from './registry';\nimport { utf8ByteLength } from './utf8';\n\nexport function registerResources(server: McpServer) {\n server.registerResource(\n 'registry-index',\n 'ply-ui://registry/index',\n {\n title: 'Registry index',\n description: 'Public Ply registry index (names, tiers, categories, description, usage, keywords, deps)',\n mimeType: 'application/json',\n },\n async (uri) => {\n const index = await fetchIndex();\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify(index, null, 2),\n },\n ],\n };\n }\n );\n\n server.registerResource(\n 'docs-llms',\n 'ply-ui://docs/llms',\n {\n title: 'llms.txt',\n description:\n 'Agent-oriented product overview (keep fetching this URL even when MCP is available)',\n mimeType: 'text/plain',\n },\n async (uri) => {\n const text = await fetchText(`${SITE_URL}/llms.txt`);\n return {\n contents: [{ uri: uri.href, mimeType: 'text/plain', text }],\n };\n }\n );\n\n server.registerResource(\n 'docs-catalog',\n 'ply-ui://docs/catalog',\n {\n title: 'AI component catalog',\n description: 'docs/ai/components.md — detailed component reference for agents',\n mimeType: 'text/markdown',\n },\n async (uri) => {\n const text = await fetchText(`${SITE_URL}/docs/ai/components.md`);\n return {\n contents: [{ uri: uri.href, mimeType: 'text/markdown', text }],\n };\n }\n );\n\n server.registerResource(\n 'docs-cursor-rules',\n 'ply-ui://docs/cursor-rules',\n {\n title: 'Cursor / Windsurf project rules',\n description:\n 'Save as .cursor/rules/ply-ui.mdc (or .windsurf/rules/ply-ui.md). Teaches assistants to write standalone zoneless Angular 22 with Ply without running MCP.',\n mimeType: 'text/markdown',\n },\n async (uri) => {\n const text = await fetchText(`${SITE_URL}/docs/ai/ply-ui.mdc`);\n return {\n contents: [{ uri: uri.href, mimeType: 'text/markdown', text }],\n };\n }\n );\n\n server.registerResource(\n 'docs-snippets',\n 'ply-ui://docs/snippets',\n {\n title: 'VS Code / Cursor snippets',\n description:\n 'Save as .vscode/ply-ui.code-snippets. Prefixes like ply-card expand usage markup after CLI install.',\n mimeType: 'application/json',\n },\n async (uri) => {\n const text = await fetchText(`${SITE_URL}/docs/ai/ply-ui.code-snippets`);\n return {\n contents: [{ uri: uri.href, mimeType: 'application/json', text }],\n };\n }\n );\n\n server.registerResource(\n 'component',\n new ResourceTemplate('ply-ui://component/{name}', {\n list: undefined,\n }),\n {\n title: 'Component metadata',\n description:\n 'Registry metadata for one component. Free source files are listed without content; Pro never streams source via MCP in V1.',\n mimeType: 'application/json',\n },\n async (uri, vars) => {\n const name = String(vars.name || '');\n if (!isSafeItemName(name)) {\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify({ error: `Invalid name: ${name}` }),\n },\n ],\n };\n }\n const index = await fetchIndex();\n const entry = index.find((i) => i.name === name);\n if (!entry) {\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify({ error: `Unknown component: ${name}` }),\n },\n ],\n };\n }\n\n if (entry.tier === 'pro') {\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify(\n {\n ...entry,\n files: null,\n note: `Pro — metadata only. ${SITE_URL}/pricing`,\n },\n null,\n 2\n ),\n },\n ],\n };\n }\n\n const item = await fetchFreeItem(name);\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify(\n {\n name: item.name,\n tier: item.tier,\n category: item.category,\n description: item.description,\n usage: item.usage,\n keywords: item.keywords,\n dependencies: item.dependencies,\n registryDependencies: item.registryDependencies,\n files: item.files.map((f) => ({\n path: f.name,\n bytes: utf8ByteLength(f.content),\n })),\n },\n null,\n 2\n ),\n },\n ],\n };\n }\n );\n}\n","/**\n * Thin registry client — mirrors packages/cli/src/registry.ts URLs/schemas\n * so the MCP server can return structured JSON without parsing CLI stdout.\n * Install/write side effects still go through ply-ui-cli (canonical path).\n */\nimport { z } from 'zod';\n\nexport const SITE_URL = 'https://ply-ui.com';\nexport const GITHUB_HUB_URL = 'https://github.com/ply-ui-ng/ply';\n\nconst env =\n typeof process !== 'undefined' && process.env ? process.env : ({} as Record<string, string | undefined>);\n\nfunction firstEnv(...names: string[]): string | undefined {\n for (const name of names) {\n const v = env[name]?.trim();\n if (v) return v;\n }\n}\n\nexport const FREE_REGISTRY_URL =\n firstEnv('PLY_REGISTRY_URL', 'BASE_UI_REGISTRY_URL') || `${SITE_URL}/registry`;\n\nexport const PRO_REGISTRY_URL =\n firstEnv('PLY_PRO_REGISTRY_URL', 'BASE_UI_PRO_REGISTRY_URL') ||\n 'https://pro.ply-ui.com/registry';\n\nconst registryFileSchema = z.object({\n name: z.string(),\n content: z.string(),\n});\n\nexport const registryItemSchema = z.object({\n name: z.string(),\n tier: z.enum(['free', 'pro']),\n category: z\n .enum(['application', 'page-layout', 'block', 'widget', 'shell', 'component'])\n .optional()\n .default('component'),\n dependencies: z.array(z.string()).default([]),\n registryDependencies: z.array(z.string()).default([]),\n description: z.string().optional().default(''),\n usage: z.string().optional().default(''),\n keywords: z.array(z.string()).optional().default([]),\n files: z.array(registryFileSchema),\n type: z.string().optional(),\n license: z.enum(['MIT', 'Ply Pro']).optional(),\n});\n\nexport const registryIndexSchema = z.array(registryItemSchema.omit({ files: true }));\n\nexport type RegistryItem = z.infer<typeof registryItemSchema>;\nexport type RegistryIndexEntry = z.infer<typeof registryIndexSchema>[number];\n\nexport type Category = NonNullable<RegistryIndexEntry['category']>;\n\nexport function itemLicense(tier: 'free' | 'pro'): 'MIT' | 'Ply Pro' {\n return tier === 'pro' ? 'Ply Pro' : 'MIT';\n}\n\nexport function hubSourceUrl(name: string): string {\n return `${GITHUB_HUB_URL}/tree/main/components/${name}`;\n}\n\nexport function itemHaystack(\n item: Pick<RegistryIndexEntry, 'name' | 'description' | 'usage' | 'keywords'>\n): string {\n return [item.name, item.description, item.usage, ...(item.keywords ?? [])]\n .filter(Boolean)\n .join(' ')\n .toLowerCase();\n}\n\nexport function isSafeItemName(name: string): boolean {\n return /^[a-z0-9][a-z0-9-.]*$/i.test(name) && !name.includes('..');\n}\n\nasync function fetchJson(url: string, headers: Record<string, string> = {}): Promise<unknown> {\n let res: Response;\n try {\n res = await fetch(url, { headers });\n } catch (err: any) {\n throw new Error(\n `Network error while contacting the registry (${err.message}). Check your connection and try again.`\n );\n }\n if (res.status === 401 || res.status === 403) {\n throw new Error(\n `License rejected (HTTP ${res.status}). Check PLY_LICENSE_KEY, or see ${SITE_URL}/pricing.`\n );\n }\n if (res.status === 404) {\n const e: any = new Error('Not found');\n e.code = 'NOT_FOUND';\n throw e;\n }\n if (!res.ok) {\n throw new Error(`Registry request failed (HTTP ${res.status}) for ${url}.`);\n }\n return res.json();\n}\n\nexport async function fetchIndex(): Promise<RegistryIndexEntry[]> {\n const data = await fetchJson(`${FREE_REGISTRY_URL}/index.json`);\n return registryIndexSchema.parse(data);\n}\n\n/** Free registry item only — V1 never streams Pro source through MCP. */\nexport async function fetchFreeItem(name: string): Promise<RegistryItem> {\n if (!isSafeItemName(name)) {\n throw new Error(`Invalid component name: '${name}'.`);\n }\n const data = await fetchJson(`${FREE_REGISTRY_URL}/styles/default/${name}.json`);\n return registryItemSchema.parse(data);\n}\n\nexport async function fetchText(url: string): Promise<string> {\n let res: Response;\n try {\n res = await fetch(url);\n } catch (err: any) {\n throw new Error(`Network error fetching ${url}: ${err.message}`);\n }\n if (!res.ok) {\n throw new Error(`Failed to fetch ${url} (HTTP ${res.status}).`);\n }\n return res.text();\n}\n\n/** Closest names to `query`, for search / suggestions. */\nexport function suggestNames(query: string, names: string[], limit = 8): string[] {\n const q = query.toLowerCase().trim();\n if (!q) return [];\n const scored = names\n .map((name) => {\n const n = name.toLowerCase();\n let score: number;\n if (n === q) score = 0;\n else if (n.startsWith(q) || q.startsWith(n)) score = 1;\n else if (n.includes(q) || q.includes(n)) score = 2;\n else score = 3 + levenshtein(q, n);\n return { name, score };\n })\n .filter((s) => s.score <= 6)\n .sort((a, b) => a.score - b.score || a.name.localeCompare(b.name));\n return scored.slice(0, limit).map((s) => s.name);\n}\n\nfunction levenshtein(a: string, b: string): number {\n const m = a.length;\n const n = b.length;\n if (!m) return n;\n if (!n) return m;\n let prev = Array.from({ length: n + 1 }, (_, i) => i);\n for (let i = 1; i <= m; i++) {\n const curr = [i];\n for (let j = 1; j <= n; j++) {\n curr[j] = Math.min(\n prev[j] + 1,\n curr[j - 1] + 1,\n prev[j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1)\n );\n }\n prev = curr;\n }\n return prev[n];\n}\n","/** UTF-8 byte length without Node `Buffer` (Workers / browsers). */\nexport function utf8ByteLength(text: string): number {\n return new TextEncoder().encode(text).byteLength;\n}\n","import { z } from 'zod';\nimport {\n SITE_URL,\n fetchFreeItem,\n fetchIndex,\n hubSourceUrl,\n isSafeItemName,\n itemLicense,\n suggestNames,\n} from '../registry';\nimport { cliAddCommand, installHint } from '../install-hint';\nimport { failJson, okJson } from '../result';\nimport { utf8ByteLength } from '../utf8';\n\nexport const getComponentInput = {\n name: z.string().describe('Registry component name (e.g. button, card)'),\n includeSource: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'If true, include free-tier source file contents. Pro source is never returned via MCP in V1.'\n ),\n};\n\nexport async function getComponent(args: { name: string; includeSource?: boolean }) {\n try {\n const name = args.name.trim();\n if (!isSafeItemName(name)) {\n return failJson(`Invalid component name: '${name}'.`);\n }\n\n const index = await fetchIndex();\n const entry = index.find((i) => i.name === name);\n if (!entry) {\n const suggestions = suggestNames(\n name,\n index.map((i) => i.name)\n );\n return failJson(`Unknown component: '${name}'.`, {\n suggestions,\n listHint: 'Call list_components or search_components.',\n });\n }\n\n const base = {\n ok: true as const,\n name: entry.name,\n tier: entry.tier,\n license: entry.license || itemLicense(entry.tier),\n category: entry.category || 'component',\n description: entry.description || '',\n usage: entry.usage || '',\n keywords: entry.keywords || [],\n dependencies: entry.dependencies,\n registryDependencies: entry.registryDependencies,\n docsUrl: `${SITE_URL}/base-elements/${entry.name}/`,\n pricingUrl: `${SITE_URL}/pricing`,\n };\n\n if (entry.tier === 'pro') {\n return okJson({\n ...base,\n source: null,\n sourceUrl: null,\n installCommand: cliAddCommand(name),\n note: `Pro component — metadata only. ${installHint(name)} Pro install also needs PLY_LICENSE_KEY. Buy at ${SITE_URL}/pricing.`,\n });\n }\n\n const item = await fetchFreeItem(name);\n const files = item.files.map((f) => ({\n path: f.name,\n bytes: utf8ByteLength(f.content),\n ...(args.includeSource ? { content: f.content } : {}),\n }));\n\n return okJson({\n ...base,\n files,\n includeSource: Boolean(args.includeSource),\n sourceUrl: hubSourceUrl(name),\n installCommand: cliAddCommand(name),\n note: args.includeSource\n ? `Free source included for reading. ${installHint(name)}`\n : `Source omitted by default. Pass includeSource=true to read free files here. ${installHint(name)}`,\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","/** Public npm / npx names for the Ply CLI and MCP. */\nexport const CLI_PACKAGE = 'ply-ui-cli';\nexport const CLI_BIN = 'ply-ui-cli';\nexport const CLI_NPX = `npx ${CLI_BIN}`;\nexport const MCP_PACKAGE = 'ply-ui-mcp';\nexport const MCP_NPX = `npx -y ${MCP_PACKAGE}`;\nexport const MCP_SERVER_NAME = 'ply';\n","import { CLI_NPX } from './brand';\n\n/** Copy-paste installer. Hosted catalog MCP cannot write files. */\nexport function cliAddCommand(name?: string): string {\n return name?.trim()\n ? `${CLI_NPX} add ${name.trim()}`\n : `${CLI_NPX} add <name>`;\n}\n\nexport function installHint(name?: string): string {\n return (\n `This catalog does not write files. Install in the project with \\`${cliAddCommand(name)}\\`. ` +\n 'Local stdio MCP (Cursor, Claude Code) can call add_components instead.'\n );\n}\n","import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\n\nexport function okJson(data: unknown): CallToolResult {\n return {\n content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],\n };\n}\n\nexport function failJson(\n message: string,\n extra: Record<string, unknown> = {}\n): CallToolResult {\n return {\n isError: true,\n content: [\n {\n type: 'text',\n text: JSON.stringify({ ok: false, error: message, ...extra }, null, 2),\n },\n ],\n };\n}\n","import { z } from 'zod';\nimport { fetchIndex, itemHaystack, itemLicense, type Category } from '../registry';\nimport { installHint } from '../install-hint';\nimport { failJson, okJson } from '../result';\n\nconst CATEGORIES = [\n 'application',\n 'page-layout',\n 'block',\n 'widget',\n 'shell',\n 'component',\n] as const satisfies readonly Category[];\n\nexport const listComponentsInput = {\n tier: z\n .enum(['free', 'pro', 'all'])\n .optional()\n .default('all')\n .describe('Filter by license tier'),\n category: z\n .enum(CATEGORIES)\n .optional()\n .describe('Filter by registry category'),\n q: z\n .string()\n .optional()\n .describe('Substring filter on name, description, usage, or keywords (case-insensitive)'),\n};\n\nexport async function listComponents(args: {\n tier?: 'free' | 'pro' | 'all';\n category?: Category;\n q?: string;\n}) {\n try {\n const index = await fetchIndex();\n const tier = args.tier ?? 'all';\n const q = args.q?.trim().toLowerCase();\n\n let items = index;\n if (tier !== 'all') {\n items = items.filter((i) => i.tier === tier);\n }\n if (args.category) {\n items = items.filter((i) => (i.category || 'component') === args.category);\n }\n if (q) {\n items = items.filter((i) => itemHaystack(i).includes(q));\n }\n\n items = [...items].sort((a, b) => a.name.localeCompare(b.name));\n\n return okJson({\n ok: true,\n count: items.length,\n items: items.map((i) => ({\n name: i.name,\n tier: i.tier,\n license: i.license || itemLicense(i.tier),\n category: i.category || 'component',\n description: i.description || '',\n usage: i.usage || '',\n keywords: i.keywords || [],\n dependencies: i.dependencies,\n registryDependencies: i.registryDependencies,\n })),\n hint: `Use get_component for details. ${installHint()}`,\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","import { z } from 'zod';\nimport { canonicalComponentName } from '../aliases';\nimport { fetchIndex, itemHaystack, suggestNames, itemLicense, type Category } from '../registry';\nimport { installHint } from '../install-hint';\nimport { failJson, okJson } from '../result';\n\nconst CATEGORIES = [\n 'application',\n 'page-layout',\n 'block',\n 'widget',\n 'shell',\n 'component',\n] as const satisfies readonly Category[];\n\nexport const searchComponentsInput = {\n query: z\n .string()\n .min(1)\n .describe('Natural-language or substring query (e.g. \"dialog modal\", \"button\"). Matches name, description, usage, and keywords.'),\n tier: z\n .enum(['free', 'pro', 'all'])\n .optional()\n .default('all')\n .describe('Filter by license tier'),\n category: z.enum(CATEGORIES).optional().describe('Filter by registry category'),\n limit: z.number().int().min(1).max(40).optional().default(12),\n};\n\nfunction tokenize(query: string): string[] {\n return query\n .toLowerCase()\n .split(/[^a-z0-9]+/i)\n .map((t) => t.trim())\n .filter((t) => t.length >= 2);\n}\n\nexport async function searchComponents(args: {\n query: string;\n tier?: 'free' | 'pro' | 'all';\n category?: Category;\n limit?: number;\n}) {\n try {\n const index = await fetchIndex();\n const tier = args.tier ?? 'all';\n const limit = args.limit ?? 12;\n const rawQuery = args.query.trim();\n const canonical = canonicalComponentName(rawQuery);\n const variants = [...new Set([rawQuery, canonical].filter(Boolean))];\n\n let pool = index;\n if (tier !== 'all') {\n pool = pool.filter((i) => i.tier === tier);\n }\n if (args.category) {\n pool = pool.filter((i) => (i.category || 'component') === args.category);\n }\n\n const names = pool.map((i) => i.name);\n const byFuzzy = new Set(variants.flatMap((q) => suggestNames(q, names, limit)));\n\n const byTokens = pool.filter((i) => {\n const hay = itemHaystack(i);\n return variants.some((q) => {\n const tokens = tokenize(q);\n return tokens.length > 0 && tokens.every((t) => hay.includes(t));\n });\n });\n\n const ranked = [\n ...byTokens.sort((a, b) => a.name.localeCompare(b.name)),\n ...pool\n .filter((i) => byFuzzy.has(i.name) && !byTokens.some((t) => t.name === i.name))\n .sort(\n (a, b) =>\n [...byFuzzy].indexOf(a.name) - [...byFuzzy].indexOf(b.name)\n ),\n ].slice(0, limit);\n\n return okJson({\n ok: true,\n query: args.query,\n count: ranked.length,\n matches: ranked.map((i) => ({\n name: i.name,\n tier: i.tier,\n license: i.license || itemLicense(i.tier),\n category: i.category || 'component',\n description: i.description || '',\n usage: i.usage || '',\n keywords: i.keywords || [],\n registryDependencies: i.registryDependencies,\n })),\n hint: `Next: get_component for details. ${installHint()}`,\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","/** Keep in sync with packages/cli/src/aliases.ts */\nexport const COMPONENT_ALIASES: Record<string, string> = {\n sheet: 'drawer',\n 'side-sheet': 'drawer',\n gallery: 'slider',\n 'image-slider': 'slider',\n slideshow: 'slider',\n range: 'range-slider',\n 'slider-input': 'range-slider',\n 'input-slider': 'range-slider',\n 'base-list-item': 'ply-list-item',\n 'base-tab-icon': 'ply-tab-icon',\n 'base-group-button': 'ply-group-button',\n 'base-dropdown-menu-item': 'ply-dropdown-menu-item',\n 'base-context-menu-item': 'ply-context-menu-item',\n};\n\nexport function canonicalComponentName(name: string): string {\n const key = name.trim().toLowerCase();\n return COMPONENT_ALIASES[key] ?? name.trim();\n}\n","{\n \"name\": \"ply-ui-mcp\",\n \"version\": \"0.1.30\",\n \"description\": \"Ply MCP server — stdio or Streamable HTTP (--http). List, search, init, doctor, diff, update, and add Angular + Tailwind components (Pro with PLY_LICENSE_KEY). Not MUI Base UI.\",\n \"type\": \"commonjs\",\n \"main\": \"dist/index.js\",\n \"bin\": {\n \"ply-ui-mcp\": \"dist/index.js\"\n },\n \"files\": [\n \"dist\",\n \"README.md\",\n \"LICENSE\"\n ],\n \"engines\": {\n \"node\": \">=18\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"start\": \"node dist/index.js\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run\",\n \"prepublishOnly\": \"npm run build\"\n },\n \"keywords\": [\n \"mcp\",\n \"model-context-protocol\",\n \"angular\",\n \"tailwindcss\",\n \"ply\",\n \"ply-ui\",\n \"ply-ui-mcp\",\n \"cli\"\n ],\n \"author\": \"Lussos\",\n \"license\": \"MIT\",\n \"mcpName\": \"io.github.ply-ui-ng/ply-ui\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/ply-ui-ng/ply.git\",\n \"directory\": \"packages/mcp\"\n },\n \"homepage\": \"https://ply-ui.com\",\n \"bugs\": {\n \"url\": \"https://github.com/ply-ui-ng/ply/issues\"\n },\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org/\"\n },\n \"dependencies\": {\n \"@modelcontextprotocol/sdk\": \"^1.32.1\",\n \"zod\": \"^4.6.2\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^26.5.1\",\n \"tsup\": \"^9.0.0\",\n \"typescript\": \"^7.0.2\",\n \"vitest\": \"^5.0.0\"\n },\n \"overrides\": {\n \"esbuild\": \"0.28.2\",\n \"fast-uri\": \"3.1.8\",\n \"proxy-addr\": \"2.0.8\",\n \"hono\": \"4.13.7\",\n \"qs\": \"6.16.0\"\n }\n}\n","import packageJson from '../package.json' with { type: 'json' };\n\n/** Bundled from packages/mcp/package.json by tsup and by the Workers deploy. */\nexport const PACKAGE_VERSION: string = packageJson.version;\n","import { z } from 'zod';\nimport { resolveProjectCwd, runCli } from '../cli';\nimport {\n SITE_URL,\n fetchIndex,\n isSafeItemName,\n suggestNames,\n} from '../registry';\nimport { failJson, okJson } from '../result';\nimport { canonicalComponentName } from '../aliases';\nimport { CLI_BIN, CLI_NPX } from '../brand';\n\nexport const addComponentsInput = {\n names: z\n .array(z.string().min(1))\n .min(1)\n .describe('One or more registry component names to install (aliases like sheet → drawer are resolved)'),\n cwd: z\n .string()\n .optional()\n .describe(\n 'Project root containing ply-ui.json (defaults to MCP process cwd / PLY_CWD / BASE_UI_CWD)'\n ),\n overwrite: z\n .boolean()\n .optional()\n .default(false)\n .describe('Overwrite existing component folders (maps to CLI --overwrite)'),\n licenseKey: z\n .string()\n .optional()\n .describe(\n 'Ply Pro license. Prefer PLY_LICENSE_KEY (or BASE_UI_LICENSE_KEY) in the MCP server env instead of putting a key in chat.'\n ),\n};\n\n/**\n * Installs registry components via the CLI. Pro names require\n * `licenseKey` or `PLY_LICENSE_KEY` / `BASE_UI_LICENSE_KEY`.\n */\nexport async function addComponents(args: {\n names: string[];\n cwd?: string;\n overwrite?: boolean;\n licenseKey?: string;\n}) {\n try {\n const cwd = resolveProjectCwd(args.cwd);\n const names = [\n ...new Set(\n args.names\n .map((n) => canonicalComponentName(n.trim()))\n .filter(Boolean)\n ),\n ];\n\n if (!names.length) {\n return failJson('Provide at least one component name.');\n }\n\n for (const name of names) {\n if (!isSafeItemName(name)) {\n return failJson(`Invalid component name: '${name}'.`);\n }\n }\n\n const index = await fetchIndex();\n const byName = new Map(index.map((i) => [i.name, i]));\n const unknown: string[] = [];\n const pro: string[] = [];\n const free: string[] = [];\n\n for (const name of names) {\n const entry = byName.get(name);\n if (!entry) {\n unknown.push(name);\n continue;\n }\n if (entry.tier === 'pro') {\n pro.push(name);\n } else {\n free.push(name);\n }\n }\n\n if (unknown.length) {\n return failJson('Unknown component name(s).', {\n unknown,\n suggestions: unknown.flatMap((n) =>\n suggestNames(\n n,\n index.map((i) => i.name),\n 3\n )\n ),\n });\n }\n\n const licenseKey =\n args.licenseKey?.trim() ||\n process.env.PLY_LICENSE_KEY?.trim() ||\n process.env.BASE_UI_LICENSE_KEY?.trim() ||\n '';\n\n if (pro.length && !licenseKey) {\n return failJson(\n `Pro components need PLY_LICENSE_KEY (or licenseKey): ${pro.join(', ')}.`,\n {\n pro,\n pricingUrl: `${SITE_URL}/pricing`,\n note: 'Set PLY_LICENSE_KEY on the MCP server process (BASE_UI_LICENSE_KEY still works), then retry. Free components can still be added with this tool.',\n freeCandidates: free,\n }\n );\n }\n\n // Also reject if free items pull Pro registryDependencies (closure).\n const queue = [...free];\n const seen = new Set<string>();\n const proDeps: string[] = [];\n while (queue.length) {\n const name = queue.shift()!;\n if (seen.has(name)) continue;\n seen.add(name);\n const entry = byName.get(name);\n if (!entry) continue;\n if (entry.tier === 'pro') {\n proDeps.push(name);\n continue;\n }\n queue.push(...entry.registryDependencies);\n }\n if (proDeps.length && !licenseKey) {\n return failJson(\n `Install blocked: free selection depends on Pro components: ${proDeps.join(', ')}.`,\n {\n proDependencies: proDeps,\n pricingUrl: `${SITE_URL}/pricing`,\n }\n );\n }\n\n const toInstall = [...free, ...pro];\n const cliArgs = ['add', ...toInstall, '--yes'];\n if (args.overwrite) cliArgs.push('--overwrite');\n\n const result = await runCli(cliArgs, {\n cwd,\n env: licenseKey\n ? { PLY_LICENSE_KEY: licenseKey, BASE_UI_LICENSE_KEY: licenseKey }\n : undefined,\n });\n if (!result.ok) {\n return failJson(`${CLI_BIN} add failed.`, {\n cwd,\n names: toInstall,\n exitCode: result.code,\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim(),\n hint: `Ensure the project was initialized (${CLI_NPX} init --yes). CLI remains the canonical install path.`,\n });\n }\n\n return okJson({\n ok: true,\n cwd,\n installed: toInstall,\n cli: `${CLI_BIN} add --yes`,\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim() || undefined,\n note: `Files were written by ${CLI_BIN} (canonical installer). MCP does not replace the CLI.`,\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { spawn } from 'child_process';\nimport { CLI_PACKAGE } from './brand';\n\n/**\n * Resolve the ply-ui-cli entrypoint.\n * Order: PLY_CLI_PATH → local monorepo dist → node_modules bin → npx.\n */\nexport function resolveCliEntrypoint(): { command: string; argsPrefix: string[] } {\n const envPath = process.env.PLY_CLI_PATH?.trim() || process.env.BASE_UI_CLI_PATH?.trim();\n if (envPath && fs.existsSync(envPath)) {\n return { command: process.execPath, argsPrefix: [envPath] };\n }\n\n const sibling = path.resolve(__dirname, '../../cli/dist/index.js');\n if (fs.existsSync(sibling)) {\n return { command: process.execPath, argsPrefix: [sibling] };\n }\n\n for (const pkg of [CLI_PACKAGE, 'base-ui-cli']) {\n try {\n const pkgJson = require.resolve(`${pkg}/package.json`);\n const bin = path.join(path.dirname(pkgJson), 'dist', 'index.js');\n if (fs.existsSync(bin)) {\n return { command: process.execPath, argsPrefix: [bin] };\n }\n } catch {\n // not installed as a dependency\n }\n }\n\n // npx.cmd is named directly so the child process never needs a shell — see\n // the spawn call below, which deliberately does not set `shell`.\n return { command: process.platform === 'win32' ? 'npx.cmd' : 'npx', argsPrefix: ['-y', CLI_PACKAGE] };\n}\n\nexport interface RunCliResult {\n ok: boolean;\n code: number | null;\n stdout: string;\n stderr: string;\n}\n\nexport function runCli(\n cliArgs: string[],\n options: { cwd: string; env?: NodeJS.ProcessEnv; timeoutMs?: number } = { cwd: process.cwd() }\n): Promise<RunCliResult> {\n const { command, argsPrefix } = resolveCliEntrypoint();\n const args = [...argsPrefix, ...cliArgs];\n const timeoutMs = options.timeoutMs ?? 120_000;\n\n return new Promise((resolve) => {\n const child = spawn(command, args, {\n cwd: options.cwd,\n env: { ...process.env, ...options.env, FORCE_COLOR: '0' },\n });\n\n let stdout = '';\n let stderr = '';\n let settled = false;\n\n const timer = setTimeout(() => {\n if (settled) return;\n settled = true;\n child.kill('SIGTERM');\n resolve({\n ok: false,\n code: null,\n stdout,\n stderr: stderr + `\\nTimed out after ${timeoutMs}ms`,\n });\n }, timeoutMs);\n\n child.stdout.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf8');\n });\n child.stderr.on('data', (chunk: Buffer) => {\n stderr += chunk.toString('utf8');\n });\n child.on('error', (err) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve({ ok: false, code: null, stdout, stderr: err.message });\n });\n child.on('close', (code) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve({ ok: code === 0, code, stdout, stderr });\n });\n });\n}\n\n/** Project root for mutating tools (init/add). Prefer explicit cwd, else process cwd. */\nexport function resolveProjectCwd(cwd?: string): string {\n const root = cwd?.trim() || process.env.PLY_CWD?.trim() || process.env.BASE_UI_CWD?.trim() || process.cwd();\n return path.resolve(root);\n}\n","import { z } from 'zod';\nimport { resolveProjectCwd, runCli } from '../cli';\nimport { isSafeItemName } from '../registry';\nimport { failJson, okJson } from '../result';\nimport { CLI_BIN } from '../brand';\n\nexport const diffComponentsInput = {\n names: z\n .array(z.string().min(1))\n .optional()\n .describe(\n 'Tracked component names to diff. Omit or pass [] to check every component in ply-ui-lock.json.'\n ),\n cwd: z\n .string()\n .optional()\n .describe(\n 'Project root containing ply-ui.json (defaults to MCP process cwd / PLY_CWD)'\n ),\n};\n\nexport async function diffComponents(args: { names?: string[]; cwd?: string } = {}) {\n try {\n const cwd = resolveProjectCwd(args.cwd);\n const names = (args.names ?? []).map((n) => n.trim()).filter(Boolean);\n for (const name of names) {\n if (!isSafeItemName(name)) {\n return failJson(`Invalid component name: '${name}'.`);\n }\n }\n\n const cliArgs = names.length ? ['diff', ...names] : ['diff'];\n const result = await runCli(cliArgs, { cwd });\n if (!result.ok) {\n return failJson(`${CLI_BIN} diff failed.`, {\n cwd,\n names,\n exitCode: result.code,\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim(),\n hint: 'Project must be initialized and components tracked in ply-ui-lock.json.',\n });\n }\n\n return okJson({\n ok: true,\n cwd,\n names: names.length ? names : 'all-tracked',\n cli: names.length ? `${CLI_BIN} diff ${names.join(' ')}` : `${CLI_BIN} diff`,\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim() || undefined,\n note: 'Read-only. Use update_components to apply upstream changes.',\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","import { z } from 'zod';\nimport { resolveProjectCwd, runCli } from '../cli';\nimport { failJson, okJson } from '../result';\nimport { CLI_BIN } from '../brand';\n\nexport const doctorInput = {\n cwd: z\n .string()\n .optional()\n .describe(\n 'Project root containing ply-ui.json (defaults to MCP process cwd / PLY_CWD). Read-only.'\n ),\n};\n\nexport async function doctor(args: { cwd?: string } = {}) {\n try {\n const cwd = resolveProjectCwd(args.cwd);\n const result = await runCli(['doctor'], { cwd });\n const body = {\n cwd,\n cli: `${CLI_BIN} doctor`,\n exitCode: result.code,\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim() || undefined,\n };\n if (!result.ok) {\n return failJson(`${CLI_BIN} doctor reported problems.`, body);\n }\n return okJson({ ok: true, ...body });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","import { z } from 'zod';\nimport { resolveProjectCwd, runCli } from '../cli';\nimport { failJson, okJson } from '../result';\nimport { CLI_BIN, CLI_NPX } from '../brand';\n\nexport const initProjectInput = {\n cwd: z\n .string()\n .optional()\n .describe(\n 'Project root to initialize (defaults to MCP process cwd / PLY_CWD). Always non-interactive (`init --yes`).'\n ),\n};\n\nexport async function initProject(args: { cwd?: string } = {}) {\n try {\n const cwd = resolveProjectCwd(args.cwd);\n const result = await runCli(['init', '--yes'], { cwd });\n if (!result.ok) {\n return failJson(`${CLI_BIN} init failed.`, {\n cwd,\n exitCode: result.code,\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim(),\n hint: `CLI remains the canonical installer: ${CLI_NPX} init --yes`,\n });\n }\n return okJson({\n ok: true,\n cwd,\n cli: `${CLI_BIN} init --yes`,\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim() || undefined,\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","import { z } from 'zod';\nimport { resolveProjectCwd, runCli } from '../cli';\nimport { isSafeItemName } from '../registry';\nimport { failJson, okJson } from '../result';\nimport { CLI_BIN } from '../brand';\n\nexport const updateComponentsInput = {\n names: z\n .array(z.string().min(1))\n .optional()\n .describe(\n 'Tracked component names to update. Omit or pass [] to update every component in ply-ui-lock.json.'\n ),\n cwd: z\n .string()\n .optional()\n .describe(\n 'Project root containing ply-ui.json (defaults to MCP process cwd / PLY_CWD)'\n ),\n force: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'On conflict (both local and upstream changed), take the upstream version. Does not revert local-only edits.'\n ),\n overwriteLocal: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'Also revert files you edited that upstream did not change (`--overwrite-local`). Default skips those files.'\n ),\n merge: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'On conflict, apply a 3-way merge using the installed snapshot (`--merge`). force still wins.'\n ),\n};\n\n/**\n * Always non-interactive (`update --yes`). Conflicts are skipped unless `force`.\n * Local-only edits are skipped unless `overwriteLocal`.\n */\nexport async function updateComponents(\n args: {\n names?: string[];\n cwd?: string;\n force?: boolean;\n overwriteLocal?: boolean;\n merge?: boolean;\n } = {}\n) {\n try {\n const cwd = resolveProjectCwd(args.cwd);\n const names = (args.names ?? []).map((n) => n.trim()).filter(Boolean);\n for (const name of names) {\n if (!isSafeItemName(name)) {\n return failJson(`Invalid component name: '${name}'.`);\n }\n }\n\n const cliArgs = ['update', ...names, '--yes'];\n if (args.force) cliArgs.push('--force');\n if (args.overwriteLocal) cliArgs.push('--overwrite-local');\n if (args.merge) cliArgs.push('--merge');\n\n const result = await runCli(cliArgs, { cwd });\n if (!result.ok) {\n return failJson(`${CLI_BIN} update failed.`, {\n cwd,\n names,\n exitCode: result.code,\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim(),\n hint: 'Run diff_components first. Conflicts need --force; local-only edits need overwriteLocal.',\n });\n }\n\n return okJson({\n ok: true,\n cwd,\n names: names.length ? names : 'all-tracked',\n force: Boolean(args.force),\n overwriteLocal: Boolean(args.overwriteLocal),\n merge: Boolean(args.merge),\n cli: [CLI_BIN, ...cliArgs].join(' '),\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim() || undefined,\n note: `Files were written by ${CLI_BIN} (canonical updater). MCP does not replace the CLI.`,\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { createCatalogMcpServer } from './catalog';\nimport { addComponents, addComponentsInput } from './tools/add-components';\nimport { diffComponents, diffComponentsInput } from './tools/diff-components';\nimport { doctor, doctorInput } from './tools/doctor';\nimport { initProject, initProjectInput } from './tools/init-project';\nimport { updateComponents, updateComponentsInput } from './tools/update-components';\nimport { CLI_BIN } from './brand';\n\nexport { PACKAGE_VERSION } from './version';\n\nexport interface CreateMcpServerOptions {\n /** When false, mutating CLI tools are omitted (hosted catalog MCP). */\n mutating?: boolean;\n}\n\nexport function createMcpServer(options: CreateMcpServerOptions = {}): McpServer {\n const mutating = options.mutating !== false;\n const server = createCatalogMcpServer();\n\n const readOnlyAnnotations = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n } as const;\n const writeAnnotations = {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: false,\n } as const;\n\n if (mutating) {\n server.registerTool(\n 'add_components',\n {\n title: 'Add Ply components',\n description:\n `Install registry components by shelling to \\`${CLI_BIN} add --yes\\`. --yes leaves an existing component in place; pass overwrite to replace it. Pro names require PLY_LICENSE_KEY (or licenseKey). Project must already have ply-ui.json.`,\n inputSchema: addComponentsInput,\n annotations: writeAnnotations,\n },\n async (args) => addComponents(args)\n );\n\n server.registerTool(\n 'init_project',\n {\n title: 'Initialize Ply in a project',\n description:\n `Run \\`${CLI_BIN} init --yes\\` in the target directory. Writes ply-ui.json, ply-ui.css, and icon sprites only when those files are missing, discovers the stylesheet already listed in angular.json, and inserts @source when it is absent. Always non-interactive.`,\n inputSchema: initProjectInput,\n annotations: writeAnnotations,\n },\n async (args) => initProject(args)\n );\n\n server.registerTool(\n 'doctor',\n {\n title: 'Verify Ply project setup',\n description:\n `Run \\`${CLI_BIN} doctor\\` (read-only). Returns isError when the CLI exits non-zero.`,\n inputSchema: doctorInput,\n annotations: readOnlyAnnotations,\n },\n async (args) => doctor(args)\n );\n\n server.registerTool(\n 'diff_components',\n {\n title: 'Diff installed Ply components',\n description:\n `Run \\`${CLI_BIN} diff\\` against tracked components. Read-only. Omit names to check everything in ply-ui-lock.json.`,\n inputSchema: diffComponentsInput,\n annotations: readOnlyAnnotations,\n },\n async (args) => diffComponents(args)\n );\n\n server.registerTool(\n 'update_components',\n {\n title: 'Update installed Ply components',\n description:\n `Run \\`${CLI_BIN} update --yes\\`. Untouched files take upstream. Conflicts stay local and the CLI exits non-zero unless force or merge. Local-only edits skip unless overwriteLocal.`,\n inputSchema: updateComponentsInput,\n annotations: writeAnnotations,\n },\n async (args) => updateComponents(args)\n );\n }\n\n return server;\n}\n","import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport { createMcpServer, PACKAGE_VERSION } from './server';\nimport { MCP_PACKAGE } from './brand';\nimport { mcpProtectedResource, wwwAuthenticate } from './auth-metadata';\n\nexport interface HttpOptions {\n host: string;\n port: number;\n readOnly: boolean;\n authToken?: string;\n}\n\nfunction setCors(res: ServerResponse): void {\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');\n res.setHeader(\n 'Access-Control-Allow-Headers',\n 'Content-Type, Authorization, Mcp-Session-Id, MCP-Protocol-Version'\n );\n}\n\nfunction unauthorized(res: ServerResponse, resourceMetadataUrl: string): void {\n setCors(res);\n res.writeHead(401, {\n 'Content-Type': 'application/json',\n 'WWW-Authenticate': wwwAuthenticate(resourceMetadataUrl),\n });\n res.end(JSON.stringify({ error: 'Unauthorized' }));\n}\n\nfunction checkAuth(req: IncomingMessage, token?: string): boolean {\n if (!token) return true;\n const header = req.headers.authorization;\n return header === `Bearer ${token}`;\n}\n\nasync function readBody(req: IncomingMessage): Promise<unknown> {\n const chunks: Buffer[] = [];\n for await (const chunk of req) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n const raw = Buffer.concat(chunks).toString('utf8').trim();\n if (!raw) return undefined;\n return JSON.parse(raw);\n}\n\n/**\n * Streamable HTTP MCP. ChatGPT / Gemini chat apps need a public HTTPS URL\n * pointing at `/mcp`. Mutating tools only work when this process can see\n * the consumer project (local `--http`, not a remote catalog host).\n */\nexport function startHttpServer(options: HttpOptions): ReturnType<typeof createServer> {\n const server = createServer(async (req, res) => {\n try {\n const url = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`);\n\n if (req.method === 'OPTIONS') {\n setCors(res);\n res.writeHead(204);\n res.end();\n return;\n }\n\n if (url.pathname === '/' && req.method === 'GET') {\n setCors(res);\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n ok: true,\n name: MCP_PACKAGE,\n version: PACKAGE_VERSION,\n transport: 'streamable-http',\n mcp: '/mcp',\n mutating: !options.readOnly,\n })\n );\n return;\n }\n\n if (url.pathname === '/.well-known/oauth-protected-resource' && req.method === 'GET') {\n setCors(res);\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end(\n JSON.stringify(\n mcpProtectedResource(new URL('/mcp', url.origin).href, Boolean(options.authToken))\n )\n );\n return;\n }\n\n if (url.pathname !== '/mcp') {\n setCors(res);\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Not found. MCP is POST/GET /mcp.' }));\n return;\n }\n\n if (!checkAuth(req, options.authToken)) {\n unauthorized(res, new URL('/.well-known/oauth-protected-resource', url.origin).href);\n return;\n }\n\n setCors(res);\n const mcp = createMcpServer({ mutating: !options.readOnly });\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n });\n await mcp.connect(transport);\n const parsedBody = req.method === 'POST' ? await readBody(req) : undefined;\n await transport.handleRequest(req, res, parsedBody);\n } catch (err) {\n console.error(`${MCP_PACKAGE} HTTP error:`, err);\n if (!res.headersSent) {\n res.writeHead(500, { 'Content-Type': 'application/json' });\n }\n if (!res.writableEnded) {\n res.end(JSON.stringify({ error: err instanceof Error ? err.message : String(err) }));\n }\n }\n });\n\n server.listen(options.port, options.host, () => {\n const addr = server.address();\n const port = typeof addr === 'object' && addr ? addr.port : options.port;\n console.error(\n `${MCP_PACKAGE} v${PACKAGE_VERSION} Streamable HTTP on http://${options.host}:${port}/mcp` +\n (options.readOnly ? ' (read-only catalog)' : '')\n );\n });\n return server;\n}\n","/** Canonical auth.md skill. Registration is not offered; see the file. */\nexport const AUTH_MD_URL = 'https://ply-ui.com/auth.md';\n\nexport interface ProtectedResourceMetadata {\n resource: string;\n resource_name: string;\n resource_documentation: string;\n resource_logo_uri: string;\n authorization_servers: string[];\n scopes_supported: string[];\n bearer_methods_supported: string[];\n}\n\n/** RFC 9728 metadata for one MCP origin. An empty authorization_servers list means registration is off. */\nexport function mcpProtectedResource(resource: string, bearer: boolean): ProtectedResourceMetadata {\n return {\n resource,\n resource_name: 'Ply MCP',\n resource_documentation: AUTH_MD_URL,\n resource_logo_uri: 'https://ply-ui.com/assets/pwa/apple-touch-icon.png',\n authorization_servers: [],\n scopes_supported: [],\n bearer_methods_supported: bearer ? ['header'] : [],\n };\n}\n\nexport function wwwAuthenticate(resourceMetadataUrl: string): string {\n return `Bearer resource_metadata=\"${resourceMetadataUrl}\"`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,mBAAqC;;;ACRrC,IAAAA,cAA0B;;;ACA1B,iBAA4C;;;ACK5C,iBAAkB;AAEX,IAAM,WAAW;AACjB,IAAM,iBAAiB;AAE9B,IAAM,MACJ,OAAO,YAAY,eAAe,QAAQ,MAAM,QAAQ,MAAO,CAAC;AAElE,SAAS,YAAY,OAAqC;AACxD,aAAW,QAAQ,OAAO;AACxB,UAAM,IAAI,IAAI,IAAI,GAAG,KAAK;AAC1B,QAAI,EAAG,QAAO;AAAA,EAChB;AACF;AAEO,IAAM,oBACX,SAAS,oBAAoB,sBAAsB,KAAK,GAAG,QAAQ;AAE9D,IAAM,mBACX,SAAS,wBAAwB,0BAA0B,KAC3D;AAEF,IAAM,qBAAqB,aAAE,OAAO;AAAA,EAClC,MAAM,aAAE,OAAO;AAAA,EACf,SAAS,aAAE,OAAO;AACpB,CAAC;AAEM,IAAM,qBAAqB,aAAE,OAAO;AAAA,EACzC,MAAM,aAAE,OAAO;AAAA,EACf,MAAM,aAAE,KAAK,CAAC,QAAQ,KAAK,CAAC;AAAA,EAC5B,UAAU,aACP,KAAK,CAAC,eAAe,eAAe,SAAS,UAAU,SAAS,WAAW,CAAC,EAC5E,SAAS,EACT,QAAQ,WAAW;AAAA,EACtB,cAAc,aAAE,MAAM,aAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;AAAA,EAC5C,sBAAsB,aAAE,MAAM,aAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;AAAA,EACpD,aAAa,aAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE;AAAA,EAC7C,OAAO,aAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE;AAAA,EACvC,UAAU,aAAE,MAAM,aAAE,OAAO,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAAA,EACnD,OAAO,aAAE,MAAM,kBAAkB;AAAA,EACjC,MAAM,aAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,SAAS,aAAE,KAAK,CAAC,OAAO,SAAS,CAAC,EAAE,SAAS;AAC/C,CAAC;AAEM,IAAM,sBAAsB,aAAE,MAAM,mBAAmB,KAAK,EAAE,OAAO,KAAK,CAAC,CAAC;AAO5E,SAAS,YAAY,MAAyC;AACnE,SAAO,SAAS,QAAQ,YAAY;AACtC;AAEO,SAAS,aAAa,MAAsB;AACjD,SAAO,GAAG,cAAc,yBAAyB,IAAI;AACvD;AAEO,SAAS,aACd,MACQ;AACR,SAAO,CAAC,KAAK,MAAM,KAAK,aAAa,KAAK,OAAO,GAAI,KAAK,YAAY,CAAC,CAAE,EACtE,OAAO,OAAO,EACd,KAAK,GAAG,EACR,YAAY;AACjB;AAEO,SAAS,eAAe,MAAuB;AACpD,SAAO,yBAAyB,KAAK,IAAI,KAAK,CAAC,KAAK,SAAS,IAAI;AACnE;AAEA,eAAe,UAAU,KAAa,UAAkC,CAAC,GAAqB;AAC5F,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,MAAM,KAAK,EAAE,QAAQ,CAAC;AAAA,EACpC,SAAS,KAAU;AACjB,UAAM,IAAI;AAAA,MACR,gDAAgD,IAAI,OAAO;AAAA,IAC7D;AAAA,EACF;AACA,MAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,UAAM,IAAI;AAAA,MACR,0BAA0B,IAAI,MAAM,oCAAoC,QAAQ;AAAA,IAClF;AAAA,EACF;AACA,MAAI,IAAI,WAAW,KAAK;AACtB,UAAM,IAAS,IAAI,MAAM,WAAW;AACpC,MAAE,OAAO;AACT,UAAM;AAAA,EACR;AACA,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,IAAI,MAAM,iCAAiC,IAAI,MAAM,SAAS,GAAG,GAAG;AAAA,EAC5E;AACA,SAAO,IAAI,KAAK;AAClB;AAEA,eAAsB,aAA4C;AAChE,QAAM,OAAO,MAAM,UAAU,GAAG,iBAAiB,aAAa;AAC9D,SAAO,oBAAoB,MAAM,IAAI;AACvC;AAGA,eAAsB,cAAc,MAAqC;AACvE,MAAI,CAAC,eAAe,IAAI,GAAG;AACzB,UAAM,IAAI,MAAM,4BAA4B,IAAI,IAAI;AAAA,EACtD;AACA,QAAM,OAAO,MAAM,UAAU,GAAG,iBAAiB,mBAAmB,IAAI,OAAO;AAC/E,SAAO,mBAAmB,MAAM,IAAI;AACtC;AAEA,eAAsB,UAAU,KAA8B;AAC5D,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,MAAM,GAAG;AAAA,EACvB,SAAS,KAAU;AACjB,UAAM,IAAI,MAAM,0BAA0B,GAAG,KAAK,IAAI,OAAO,EAAE;AAAA,EACjE;AACA,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,IAAI,MAAM,mBAAmB,GAAG,UAAU,IAAI,MAAM,IAAI;AAAA,EAChE;AACA,SAAO,IAAI,KAAK;AAClB;AAGO,SAAS,aAAa,OAAe,OAAiB,QAAQ,GAAa;AAChF,QAAM,IAAI,MAAM,YAAY,EAAE,KAAK;AACnC,MAAI,CAAC,EAAG,QAAO,CAAC;AAChB,QAAM,SAAS,MACZ,IAAI,CAAC,SAAS;AACb,UAAM,IAAI,KAAK,YAAY;AAC3B,QAAI;AACJ,QAAI,MAAM,EAAG,SAAQ;AAAA,aACZ,EAAE,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,EAAG,SAAQ;AAAA,aAC5C,EAAE,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,EAAG,SAAQ;AAAA,QAC5C,SAAQ,IAAI,YAAY,GAAG,CAAC;AACjC,WAAO,EAAE,MAAM,MAAM;AAAA,EACvB,CAAC,EACA,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,EAC1B,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AACnE,SAAO,OAAO,MAAM,GAAG,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI;AACjD;AAEA,SAAS,YAAY,GAAW,GAAmB;AACjD,QAAM,IAAI,EAAE;AACZ,QAAM,IAAI,EAAE;AACZ,MAAI,CAAC,EAAG,QAAO;AACf,MAAI,CAAC,EAAG,QAAO;AACf,MAAI,OAAO,MAAM,KAAK,EAAE,QAAQ,IAAI,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC;AACpD,WAAS,IAAI,GAAG,KAAK,GAAG,KAAK;AAC3B,UAAM,OAAO,CAAC,CAAC;AACf,aAAS,IAAI,GAAG,KAAK,GAAG,KAAK;AAC3B,WAAK,CAAC,IAAI,KAAK;AAAA,QACb,KAAK,CAAC,IAAI;AAAA,QACV,KAAK,IAAI,CAAC,IAAI;AAAA,QACd,KAAK,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,IAAI;AAAA,MAC7C;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,SAAO,KAAK,CAAC;AACf;;;ACrKO,SAAS,eAAe,MAAsB;AACnD,SAAO,IAAI,YAAY,EAAE,OAAO,IAAI,EAAE;AACxC;;;AFOO,SAAS,kBAAkB,QAAmB;AACnD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,IACA,OAAO,QAAQ;AACb,YAAM,QAAQ,MAAM,WAAW;AAC/B,aAAO;AAAA,QACL,UAAU;AAAA,UACR;AAAA,YACE,KAAK,IAAI;AAAA,YACT,UAAU;AAAA,YACV,MAAM,KAAK,UAAU,OAAO,MAAM,CAAC;AAAA,UACrC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MACF,UAAU;AAAA,IACZ;AAAA,IACA,OAAO,QAAQ;AACb,YAAM,OAAO,MAAM,UAAU,GAAG,QAAQ,WAAW;AACnD,aAAO;AAAA,QACL,UAAU,CAAC,EAAE,KAAK,IAAI,MAAM,UAAU,cAAc,KAAK,CAAC;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,IACA,OAAO,QAAQ;AACb,YAAM,OAAO,MAAM,UAAU,GAAG,QAAQ,wBAAwB;AAChE,aAAO;AAAA,QACL,UAAU,CAAC,EAAE,KAAK,IAAI,MAAM,UAAU,iBAAiB,KAAK,CAAC;AAAA,MAC/D;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MACF,UAAU;AAAA,IACZ;AAAA,IACA,OAAO,QAAQ;AACb,YAAM,OAAO,MAAM,UAAU,GAAG,QAAQ,qBAAqB;AAC7D,aAAO;AAAA,QACL,UAAU,CAAC,EAAE,KAAK,IAAI,MAAM,UAAU,iBAAiB,KAAK,CAAC;AAAA,MAC/D;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MACF,UAAU;AAAA,IACZ;AAAA,IACA,OAAO,QAAQ;AACb,YAAM,OAAO,MAAM,UAAU,GAAG,QAAQ,+BAA+B;AACvE,aAAO;AAAA,QACL,UAAU,CAAC,EAAE,KAAK,IAAI,MAAM,UAAU,oBAAoB,KAAK,CAAC;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,IAAI,4BAAiB,6BAA6B;AAAA,MAChD,MAAM;AAAA,IACR,CAAC;AAAA,IACD;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MACF,UAAU;AAAA,IACZ;AAAA,IACA,OAAO,KAAK,SAAS;AACnB,YAAM,OAAO,OAAO,KAAK,QAAQ,EAAE;AACnC,UAAI,CAAC,eAAe,IAAI,GAAG;AACzB,eAAO;AAAA,UACL,UAAU;AAAA,YACR;AAAA,cACE,KAAK,IAAI;AAAA,cACT,UAAU;AAAA,cACV,MAAM,KAAK,UAAU,EAAE,OAAO,iBAAiB,IAAI,GAAG,CAAC;AAAA,YACzD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,YAAM,QAAQ,MAAM,WAAW;AAC/B,YAAM,QAAQ,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AAC/C,UAAI,CAAC,OAAO;AACV,eAAO;AAAA,UACL,UAAU;AAAA,YACR;AAAA,cACE,KAAK,IAAI;AAAA,cACT,UAAU;AAAA,cACV,MAAM,KAAK,UAAU,EAAE,OAAO,sBAAsB,IAAI,GAAG,CAAC;AAAA,YAC9D;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,UAAI,MAAM,SAAS,OAAO;AACxB,eAAO;AAAA,UACL,UAAU;AAAA,YACR;AAAA,cACE,KAAK,IAAI;AAAA,cACT,UAAU;AAAA,cACV,MAAM,KAAK;AAAA,gBACT;AAAA,kBACE,GAAG;AAAA,kBACH,OAAO;AAAA,kBACP,MAAM,6BAAwB,QAAQ;AAAA,gBACxC;AAAA,gBACA;AAAA,gBACA;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,OAAO,MAAM,cAAc,IAAI;AACrC,aAAO;AAAA,QACL,UAAU;AAAA,UACR;AAAA,YACE,KAAK,IAAI;AAAA,YACT,UAAU;AAAA,YACV,MAAM,KAAK;AAAA,cACT;AAAA,gBACE,MAAM,KAAK;AAAA,gBACX,MAAM,KAAK;AAAA,gBACX,UAAU,KAAK;AAAA,gBACf,aAAa,KAAK;AAAA,gBAClB,OAAO,KAAK;AAAA,gBACZ,UAAU,KAAK;AAAA,gBACf,cAAc,KAAK;AAAA,gBACnB,sBAAsB,KAAK;AAAA,gBAC3B,OAAO,KAAK,MAAM,IAAI,CAAC,OAAO;AAAA,kBAC5B,MAAM,EAAE;AAAA,kBACR,OAAO,eAAe,EAAE,OAAO;AAAA,gBACjC,EAAE;AAAA,cACJ;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AG3LA,IAAAC,cAAkB;;;ACCX,IAAM,cAAc;AACpB,IAAM,UAAU;AAChB,IAAM,UAAU,OAAO,OAAO;AAC9B,IAAM,cAAc;AACpB,IAAM,UAAU,UAAU,WAAW;AACrC,IAAM,kBAAkB;;;ACHxB,SAAS,cAAc,MAAuB;AACnD,SAAO,MAAM,KAAK,IACd,GAAG,OAAO,QAAQ,KAAK,KAAK,CAAC,KAC7B,GAAG,OAAO;AAChB;AAEO,SAAS,YAAY,MAAuB;AACjD,SACE,oEAAoE,cAAc,IAAI,CAAC;AAG3F;;;ACZO,SAAS,OAAO,MAA+B;AACpD,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,MAAM,MAAM,CAAC,EAAE,CAAC;AAAA,EACjE;AACF;AAEO,SAAS,SACd,SACA,QAAiC,CAAC,GAClB;AAChB,SAAO;AAAA,IACL,SAAS;AAAA,IACT,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM,KAAK,UAAU,EAAE,IAAI,OAAO,OAAO,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AAAA,MACvE;AAAA,IACF;AAAA,EACF;AACF;;;AHPO,IAAM,oBAAoB;AAAA,EAC/B,MAAM,cAAE,OAAO,EAAE,SAAS,6CAA6C;AAAA,EACvE,eAAe,cACZ,QAAQ,EACR,SAAS,EACT,QAAQ,KAAK,EACb;AAAA,IACC;AAAA,EACF;AACJ;AAEA,eAAsB,aAAa,MAAiD;AAClF,MAAI;AACF,UAAM,OAAO,KAAK,KAAK,KAAK;AAC5B,QAAI,CAAC,eAAe,IAAI,GAAG;AACzB,aAAO,SAAS,4BAA4B,IAAI,IAAI;AAAA,IACtD;AAEA,UAAM,QAAQ,MAAM,WAAW;AAC/B,UAAM,QAAQ,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AAC/C,QAAI,CAAC,OAAO;AACV,YAAM,cAAc;AAAA,QAClB;AAAA,QACA,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,MACzB;AACA,aAAO,SAAS,uBAAuB,IAAI,MAAM;AAAA,QAC/C;AAAA,QACA,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAEA,UAAM,OAAO;AAAA,MACX,IAAI;AAAA,MACJ,MAAM,MAAM;AAAA,MACZ,MAAM,MAAM;AAAA,MACZ,SAAS,MAAM,WAAW,YAAY,MAAM,IAAI;AAAA,MAChD,UAAU,MAAM,YAAY;AAAA,MAC5B,aAAa,MAAM,eAAe;AAAA,MAClC,OAAO,MAAM,SAAS;AAAA,MACtB,UAAU,MAAM,YAAY,CAAC;AAAA,MAC7B,cAAc,MAAM;AAAA,MACpB,sBAAsB,MAAM;AAAA,MAC5B,SAAS,GAAG,QAAQ,kBAAkB,MAAM,IAAI;AAAA,MAChD,YAAY,GAAG,QAAQ;AAAA,IACzB;AAEA,QAAI,MAAM,SAAS,OAAO;AACxB,aAAO,OAAO;AAAA,QACZ,GAAG;AAAA,QACH,QAAQ;AAAA,QACR,WAAW;AAAA,QACX,gBAAgB,cAAc,IAAI;AAAA,QAClC,MAAM,uCAAkC,YAAY,IAAI,CAAC,mDAAmD,QAAQ;AAAA,MACtH,CAAC;AAAA,IACH;AAEA,UAAM,OAAO,MAAM,cAAc,IAAI;AACrC,UAAM,QAAQ,KAAK,MAAM,IAAI,CAAC,OAAO;AAAA,MACnC,MAAM,EAAE;AAAA,MACR,OAAO,eAAe,EAAE,OAAO;AAAA,MAC/B,GAAI,KAAK,gBAAgB,EAAE,SAAS,EAAE,QAAQ,IAAI,CAAC;AAAA,IACrD,EAAE;AAEF,WAAO,OAAO;AAAA,MACZ,GAAG;AAAA,MACH;AAAA,MACA,eAAe,QAAQ,KAAK,aAAa;AAAA,MACzC,WAAW,aAAa,IAAI;AAAA,MAC5B,gBAAgB,cAAc,IAAI;AAAA,MAClC,MAAM,KAAK,gBACP,qCAAqC,YAAY,IAAI,CAAC,KACtD,+EAA+E,YAAY,IAAI,CAAC;AAAA,IACtG,CAAC;AAAA,EACH,SAAS,KAAU;AACjB,WAAO,SAAS,IAAI,WAAW,OAAO,GAAG,CAAC;AAAA,EAC5C;AACF;;;AI1FA,IAAAC,cAAkB;AAKlB,IAAM,aAAa;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,sBAAsB;AAAA,EACjC,MAAM,cACH,KAAK,CAAC,QAAQ,OAAO,KAAK,CAAC,EAC3B,SAAS,EACT,QAAQ,KAAK,EACb,SAAS,wBAAwB;AAAA,EACpC,UAAU,cACP,KAAK,UAAU,EACf,SAAS,EACT,SAAS,6BAA6B;AAAA,EACzC,GAAG,cACA,OAAO,EACP,SAAS,EACT,SAAS,8EAA8E;AAC5F;AAEA,eAAsB,eAAe,MAIlC;AACD,MAAI;AACF,UAAM,QAAQ,MAAM,WAAW;AAC/B,UAAM,OAAO,KAAK,QAAQ;AAC1B,UAAM,IAAI,KAAK,GAAG,KAAK,EAAE,YAAY;AAErC,QAAI,QAAQ;AACZ,QAAI,SAAS,OAAO;AAClB,cAAQ,MAAM,OAAO,CAAC,MAAM,EAAE,SAAS,IAAI;AAAA,IAC7C;AACA,QAAI,KAAK,UAAU;AACjB,cAAQ,MAAM,OAAO,CAAC,OAAO,EAAE,YAAY,iBAAiB,KAAK,QAAQ;AAAA,IAC3E;AACA,QAAI,GAAG;AACL,cAAQ,MAAM,OAAO,CAAC,MAAM,aAAa,CAAC,EAAE,SAAS,CAAC,CAAC;AAAA,IACzD;AAEA,YAAQ,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAE9D,WAAO,OAAO;AAAA,MACZ,IAAI;AAAA,MACJ,OAAO,MAAM;AAAA,MACb,OAAO,MAAM,IAAI,CAAC,OAAO;AAAA,QACvB,MAAM,EAAE;AAAA,QACR,MAAM,EAAE;AAAA,QACR,SAAS,EAAE,WAAW,YAAY,EAAE,IAAI;AAAA,QACxC,UAAU,EAAE,YAAY;AAAA,QACxB,aAAa,EAAE,eAAe;AAAA,QAC9B,OAAO,EAAE,SAAS;AAAA,QAClB,UAAU,EAAE,YAAY,CAAC;AAAA,QACzB,cAAc,EAAE;AAAA,QAChB,sBAAsB,EAAE;AAAA,MAC1B,EAAE;AAAA,MACF,MAAM,kCAAkC,YAAY,CAAC;AAAA,IACvD,CAAC;AAAA,EACH,SAAS,KAAU;AACjB,WAAO,SAAS,IAAI,WAAW,OAAO,GAAG,CAAC;AAAA,EAC5C;AACF;;;ACxEA,IAAAC,cAAkB;;;ACCX,IAAM,oBAA4C;AAAA,EACvD,OAAO;AAAA,EACP,cAAc;AAAA,EACd,SAAS;AAAA,EACT,gBAAgB;AAAA,EAChB,WAAW;AAAA,EACX,OAAO;AAAA,EACP,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,qBAAqB;AAAA,EACrB,2BAA2B;AAAA,EAC3B,0BAA0B;AAC5B;AAEO,SAAS,uBAAuB,MAAsB;AAC3D,QAAM,MAAM,KAAK,KAAK,EAAE,YAAY;AACpC,SAAO,kBAAkB,GAAG,KAAK,KAAK,KAAK;AAC7C;;;ADdA,IAAMC,cAAa;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,wBAAwB;AAAA,EACnC,OAAO,cACJ,OAAO,EACP,IAAI,CAAC,EACL,SAAS,sHAAsH;AAAA,EAClI,MAAM,cACH,KAAK,CAAC,QAAQ,OAAO,KAAK,CAAC,EAC3B,SAAS,EACT,QAAQ,KAAK,EACb,SAAS,wBAAwB;AAAA,EACpC,UAAU,cAAE,KAAKA,WAAU,EAAE,SAAS,EAAE,SAAS,6BAA6B;AAAA,EAC9E,OAAO,cAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE;AAC9D;AAEA,SAAS,SAAS,OAAyB;AACzC,SAAO,MACJ,YAAY,EACZ,MAAM,aAAa,EACnB,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC;AAChC;AAEA,eAAsB,iBAAiB,MAKpC;AACD,MAAI;AACF,UAAM,QAAQ,MAAM,WAAW;AAC/B,UAAM,OAAO,KAAK,QAAQ;AAC1B,UAAM,QAAQ,KAAK,SAAS;AAC5B,UAAM,WAAW,KAAK,MAAM,KAAK;AACjC,UAAM,YAAY,uBAAuB,QAAQ;AACjD,UAAM,WAAW,CAAC,GAAG,IAAI,IAAI,CAAC,UAAU,SAAS,EAAE,OAAO,OAAO,CAAC,CAAC;AAEnE,QAAI,OAAO;AACX,QAAI,SAAS,OAAO;AAClB,aAAO,KAAK,OAAO,CAAC,MAAM,EAAE,SAAS,IAAI;AAAA,IAC3C;AACA,QAAI,KAAK,UAAU;AACjB,aAAO,KAAK,OAAO,CAAC,OAAO,EAAE,YAAY,iBAAiB,KAAK,QAAQ;AAAA,IACzE;AAEA,UAAM,QAAQ,KAAK,IAAI,CAAC,MAAM,EAAE,IAAI;AACpC,UAAM,UAAU,IAAI,IAAI,SAAS,QAAQ,CAAC,MAAM,aAAa,GAAG,OAAO,KAAK,CAAC,CAAC;AAE9E,UAAM,WAAW,KAAK,OAAO,CAAC,MAAM;AAClC,YAAM,MAAM,aAAa,CAAC;AAC1B,aAAO,SAAS,KAAK,CAAC,MAAM;AAC1B,cAAM,SAAS,SAAS,CAAC;AACzB,eAAO,OAAO,SAAS,KAAK,OAAO,MAAM,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC;AAAA,MACjE,CAAC;AAAA,IACH,CAAC;AAED,UAAM,SAAS;AAAA,MACb,GAAG,SAAS,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAAA,MACvD,GAAG,KACA,OAAO,CAAC,MAAM,QAAQ,IAAI,EAAE,IAAI,KAAK,CAAC,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,EAC7E;AAAA,QACC,CAAC,GAAG,MACF,CAAC,GAAG,OAAO,EAAE,QAAQ,EAAE,IAAI,IAAI,CAAC,GAAG,OAAO,EAAE,QAAQ,EAAE,IAAI;AAAA,MAC9D;AAAA,IACJ,EAAE,MAAM,GAAG,KAAK;AAEhB,WAAO,OAAO;AAAA,MACZ,IAAI;AAAA,MACJ,OAAO,KAAK;AAAA,MACZ,OAAO,OAAO;AAAA,MACd,SAAS,OAAO,IAAI,CAAC,OAAO;AAAA,QAC1B,MAAM,EAAE;AAAA,QACR,MAAM,EAAE;AAAA,QACR,SAAS,EAAE,WAAW,YAAY,EAAE,IAAI;AAAA,QACxC,UAAU,EAAE,YAAY;AAAA,QACxB,aAAa,EAAE,eAAe;AAAA,QAC9B,OAAO,EAAE,SAAS;AAAA,QAClB,UAAU,EAAE,YAAY,CAAC;AAAA,QACzB,sBAAsB,EAAE;AAAA,MAC1B,EAAE;AAAA,MACF,MAAM,oCAAoC,YAAY,CAAC;AAAA,IACzD,CAAC;AAAA,EACH,SAAS,KAAU;AACjB,WAAO,SAAS,IAAI,WAAW,OAAO,GAAG,CAAC;AAAA,EAC5C;AACF;;;AEnGA;AAAA,EACE,MAAQ;AAAA,EACR,SAAW;AAAA,EACX,aAAe;AAAA,EACf,MAAQ;AAAA,EACR,MAAQ;AAAA,EACR,KAAO;AAAA,IACL,cAAc;AAAA,EAChB;AAAA,EACA,OAAS;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,SAAW;AAAA,IACT,MAAQ;AAAA,EACV;AAAA,EACA,SAAW;AAAA,IACT,OAAS;AAAA,IACT,KAAO;AAAA,IACP,OAAS;AAAA,IACT,WAAa;AAAA,IACb,MAAQ;AAAA,IACR,gBAAkB;AAAA,EACpB;AAAA,EACA,UAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,QAAU;AAAA,EACV,SAAW;AAAA,EACX,SAAW;AAAA,EACX,YAAc;AAAA,IACZ,MAAQ;AAAA,IACR,KAAO;AAAA,IACP,WAAa;AAAA,EACf;AAAA,EACA,UAAY;AAAA,EACZ,MAAQ;AAAA,IACN,KAAO;AAAA,EACT;AAAA,EACA,eAAiB;AAAA,IACf,UAAY;AAAA,EACd;AAAA,EACA,cAAgB;AAAA,IACd,6BAA6B;AAAA,IAC7B,KAAO;AAAA,EACT;AAAA,EACA,iBAAmB;AAAA,IACjB,eAAe;AAAA,IACf,MAAQ;AAAA,IACR,YAAc;AAAA,IACd,QAAU;AAAA,EACZ;AAAA,EACA,WAAa;AAAA,IACX,SAAW;AAAA,IACX,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,MAAQ;AAAA,IACR,IAAM;AAAA,EACR;AACF;;;AChEO,IAAM,kBAA0B,gBAAY;;;AZMnD,IAAM,qBAAqB;AAAA,EACzB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AACjB;AAGO,SAAS,yBAAoC;AAClD,QAAM,SAAS,IAAI,sBAAU;AAAA,IAC3B,MAAM;AAAA,IACN,SAAS;AAAA,EACX,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE,0LAA0L,OAAO;AAAA,MACnM,aAAa;AAAA,MACb,aAAa;AAAA,IACf;AAAA,IACA,OAAO,SAAS,eAAe,IAAI;AAAA,EACrC;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE,kMAAkM,OAAO;AAAA,MAC3M,aAAa;AAAA,MACb,aAAa;AAAA,IACf;AAAA,IACA,OAAO,SAAS,aAAa,IAAI;AAAA,EACnC;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE,6KAA6K,OAAO;AAAA,MACtL,aAAa;AAAA,MACb,aAAa;AAAA,IACf;AAAA,IACA,OAAO,SAAS,iBAAiB,IAAI;AAAA,EACvC;AAEA,oBAAkB,MAAM;AACxB,SAAO;AACT;;;Aa7DA,IAAAC,cAAkB;;;ACAlB,gBAAe;AACf,kBAAiB;AACjB,2BAAsB;AAOf,SAAS,uBAAkE;AAChF,QAAM,UAAU,QAAQ,IAAI,cAAc,KAAK,KAAK,QAAQ,IAAI,kBAAkB,KAAK;AACvF,MAAI,WAAW,UAAAC,QAAG,WAAW,OAAO,GAAG;AACrC,WAAO,EAAE,SAAS,QAAQ,UAAU,YAAY,CAAC,OAAO,EAAE;AAAA,EAC5D;AAEA,QAAM,UAAU,YAAAC,QAAK,QAAQ,WAAW,yBAAyB;AACjE,MAAI,UAAAD,QAAG,WAAW,OAAO,GAAG;AAC1B,WAAO,EAAE,SAAS,QAAQ,UAAU,YAAY,CAAC,OAAO,EAAE;AAAA,EAC5D;AAEA,aAAW,OAAO,CAAC,aAAa,aAAa,GAAG;AAC9C,QAAI;AACF,YAAM,UAAU,QAAQ,QAAQ,GAAG,GAAG,eAAe;AACrD,YAAM,MAAM,YAAAC,QAAK,KAAK,YAAAA,QAAK,QAAQ,OAAO,GAAG,QAAQ,UAAU;AAC/D,UAAI,UAAAD,QAAG,WAAW,GAAG,GAAG;AACtB,eAAO,EAAE,SAAS,QAAQ,UAAU,YAAY,CAAC,GAAG,EAAE;AAAA,MACxD;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAIA,SAAO,EAAE,SAAS,QAAQ,aAAa,UAAU,YAAY,OAAO,YAAY,CAAC,MAAM,WAAW,EAAE;AACtG;AASO,SAAS,OACd,SACA,UAAwE,EAAE,KAAK,QAAQ,IAAI,EAAE,GACtE;AACvB,QAAM,EAAE,SAAS,WAAW,IAAI,qBAAqB;AACrD,QAAM,OAAO,CAAC,GAAG,YAAY,GAAG,OAAO;AACvC,QAAM,YAAY,QAAQ,aAAa;AAEvC,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,YAAQ,4BAAM,SAAS,MAAM;AAAA,MACjC,KAAK,QAAQ;AAAA,MACb,KAAK,EAAE,GAAG,QAAQ,KAAK,GAAG,QAAQ,KAAK,aAAa,IAAI;AAAA,IAC1D,CAAC;AAED,QAAI,SAAS;AACb,QAAI,SAAS;AACb,QAAI,UAAU;AAEd,UAAM,QAAQ,WAAW,MAAM;AAC7B,UAAI,QAAS;AACb,gBAAU;AACV,YAAM,KAAK,SAAS;AACpB,cAAQ;AAAA,QACN,IAAI;AAAA,QACJ,MAAM;AAAA,QACN;AAAA,QACA,QAAQ,SAAS;AAAA,kBAAqB,SAAS;AAAA,MACjD,CAAC;AAAA,IACH,GAAG,SAAS;AAEZ,UAAM,OAAO,GAAG,QAAQ,CAAC,UAAkB;AACzC,gBAAU,MAAM,SAAS,MAAM;AAAA,IACjC,CAAC;AACD,UAAM,OAAO,GAAG,QAAQ,CAAC,UAAkB;AACzC,gBAAU,MAAM,SAAS,MAAM;AAAA,IACjC,CAAC;AACD,UAAM,GAAG,SAAS,CAAC,QAAQ;AACzB,UAAI,QAAS;AACb,gBAAU;AACV,mBAAa,KAAK;AAClB,cAAQ,EAAE,IAAI,OAAO,MAAM,MAAM,QAAQ,QAAQ,IAAI,QAAQ,CAAC;AAAA,IAChE,CAAC;AACD,UAAM,GAAG,SAAS,CAAC,SAAS;AAC1B,UAAI,QAAS;AACb,gBAAU;AACV,mBAAa,KAAK;AAClB,cAAQ,EAAE,IAAI,SAAS,GAAG,MAAM,QAAQ,OAAO,CAAC;AAAA,IAClD,CAAC;AAAA,EACH,CAAC;AACH;AAGO,SAAS,kBAAkB,KAAsB;AACtD,QAAM,OAAO,KAAK,KAAK,KAAK,QAAQ,IAAI,SAAS,KAAK,KAAK,QAAQ,IAAI,aAAa,KAAK,KAAK,QAAQ,IAAI;AAC1G,SAAO,YAAAC,QAAK,QAAQ,IAAI;AAC1B;;;ADvFO,IAAM,qBAAqB;AAAA,EAChC,OAAO,cACJ,MAAM,cAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EACvB,IAAI,CAAC,EACL,SAAS,iGAA4F;AAAA,EACxG,KAAK,cACF,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,WAAW,cACR,QAAQ,EACR,SAAS,EACT,QAAQ,KAAK,EACb,SAAS,gEAAgE;AAAA,EAC5E,YAAY,cACT,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AACJ;AAMA,eAAsB,cAAc,MAKjC;AACD,MAAI;AACF,UAAM,MAAM,kBAAkB,KAAK,GAAG;AACtC,UAAM,QAAQ;AAAA,MACZ,GAAG,IAAI;AAAA,QACL,KAAK,MACF,IAAI,CAAC,MAAM,uBAAuB,EAAE,KAAK,CAAC,CAAC,EAC3C,OAAO,OAAO;AAAA,MACnB;AAAA,IACF;AAEA,QAAI,CAAC,MAAM,QAAQ;AACjB,aAAO,SAAS,sCAAsC;AAAA,IACxD;AAEA,eAAW,QAAQ,OAAO;AACxB,UAAI,CAAC,eAAe,IAAI,GAAG;AACzB,eAAO,SAAS,4BAA4B,IAAI,IAAI;AAAA,MACtD;AAAA,IACF;AAEA,UAAM,QAAQ,MAAM,WAAW;AAC/B,UAAM,SAAS,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AACpD,UAAM,UAAoB,CAAC;AAC3B,UAAM,MAAgB,CAAC;AACvB,UAAM,OAAiB,CAAC;AAExB,eAAW,QAAQ,OAAO;AACxB,YAAM,QAAQ,OAAO,IAAI,IAAI;AAC7B,UAAI,CAAC,OAAO;AACV,gBAAQ,KAAK,IAAI;AACjB;AAAA,MACF;AACA,UAAI,MAAM,SAAS,OAAO;AACxB,YAAI,KAAK,IAAI;AAAA,MACf,OAAO;AACL,aAAK,KAAK,IAAI;AAAA,MAChB;AAAA,IACF;AAEA,QAAI,QAAQ,QAAQ;AAClB,aAAO,SAAS,8BAA8B;AAAA,QAC5C;AAAA,QACA,aAAa,QAAQ;AAAA,UAAQ,CAAC,MAC5B;AAAA,YACE;AAAA,YACA,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,YACvB;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAEA,UAAM,aACJ,KAAK,YAAY,KAAK,KACtB,QAAQ,IAAI,iBAAiB,KAAK,KAClC,QAAQ,IAAI,qBAAqB,KAAK,KACtC;AAEF,QAAI,IAAI,UAAU,CAAC,YAAY;AAC7B,aAAO;AAAA,QACL,wDAAwD,IAAI,KAAK,IAAI,CAAC;AAAA,QACtE;AAAA,UACE;AAAA,UACA,YAAY,GAAG,QAAQ;AAAA,UACvB,MAAM;AAAA,UACN,gBAAgB;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAGA,UAAM,QAAQ,CAAC,GAAG,IAAI;AACtB,UAAM,OAAO,oBAAI,IAAY;AAC7B,UAAM,UAAoB,CAAC;AAC3B,WAAO,MAAM,QAAQ;AACnB,YAAM,OAAO,MAAM,MAAM;AACzB,UAAI,KAAK,IAAI,IAAI,EAAG;AACpB,WAAK,IAAI,IAAI;AACb,YAAM,QAAQ,OAAO,IAAI,IAAI;AAC7B,UAAI,CAAC,MAAO;AACZ,UAAI,MAAM,SAAS,OAAO;AACxB,gBAAQ,KAAK,IAAI;AACjB;AAAA,MACF;AACA,YAAM,KAAK,GAAG,MAAM,oBAAoB;AAAA,IAC1C;AACA,QAAI,QAAQ,UAAU,CAAC,YAAY;AACjC,aAAO;AAAA,QACL,8DAA8D,QAAQ,KAAK,IAAI,CAAC;AAAA,QAChF;AAAA,UACE,iBAAiB;AAAA,UACjB,YAAY,GAAG,QAAQ;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAEA,UAAM,YAAY,CAAC,GAAG,MAAM,GAAG,GAAG;AAClC,UAAM,UAAU,CAAC,OAAO,GAAG,WAAW,OAAO;AAC7C,QAAI,KAAK,UAAW,SAAQ,KAAK,aAAa;AAE9C,UAAM,SAAS,MAAM,OAAO,SAAS;AAAA,MACnC;AAAA,MACA,KAAK,aACD,EAAE,iBAAiB,YAAY,qBAAqB,WAAW,IAC/D;AAAA,IACN,CAAC;AACD,QAAI,CAAC,OAAO,IAAI;AACd,aAAO,SAAS,GAAG,OAAO,gBAAgB;AAAA,QACxC;AAAA,QACA,OAAO;AAAA,QACP,UAAU,OAAO;AAAA,QACjB,QAAQ,OAAO,OAAO,KAAK;AAAA,QAC3B,QAAQ,OAAO,OAAO,KAAK;AAAA,QAC3B,MAAM,uCAAuC,OAAO;AAAA,MACtD,CAAC;AAAA,IACH;AAEA,WAAO,OAAO;AAAA,MACZ,IAAI;AAAA,MACJ;AAAA,MACA,WAAW;AAAA,MACX,KAAK,GAAG,OAAO;AAAA,MACf,QAAQ,OAAO,OAAO,KAAK;AAAA,MAC3B,QAAQ,OAAO,OAAO,KAAK,KAAK;AAAA,MAChC,MAAM,yBAAyB,OAAO;AAAA,IACxC,CAAC;AAAA,EACH,SAAS,KAAU;AACjB,WAAO,SAAS,IAAI,WAAW,OAAO,GAAG,CAAC;AAAA,EAC5C;AACF;;;AE/KA,IAAAC,cAAkB;AAMX,IAAM,sBAAsB;AAAA,EACjC,OAAO,cACJ,MAAM,cAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EACvB,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,KAAK,cACF,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AACJ;AAEA,eAAsB,eAAe,OAA2C,CAAC,GAAG;AAClF,MAAI;AACF,UAAM,MAAM,kBAAkB,KAAK,GAAG;AACtC,UAAM,SAAS,KAAK,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO;AACpE,eAAW,QAAQ,OAAO;AACxB,UAAI,CAAC,eAAe,IAAI,GAAG;AACzB,eAAO,SAAS,4BAA4B,IAAI,IAAI;AAAA,MACtD;AAAA,IACF;AAEA,UAAM,UAAU,MAAM,SAAS,CAAC,QAAQ,GAAG,KAAK,IAAI,CAAC,MAAM;AAC3D,UAAM,SAAS,MAAM,OAAO,SAAS,EAAE,IAAI,CAAC;AAC5C,QAAI,CAAC,OAAO,IAAI;AACd,aAAO,SAAS,GAAG,OAAO,iBAAiB;AAAA,QACzC;AAAA,QACA;AAAA,QACA,UAAU,OAAO;AAAA,QACjB,QAAQ,OAAO,OAAO,KAAK;AAAA,QAC3B,QAAQ,OAAO,OAAO,KAAK;AAAA,QAC3B,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAEA,WAAO,OAAO;AAAA,MACZ,IAAI;AAAA,MACJ;AAAA,MACA,OAAO,MAAM,SAAS,QAAQ;AAAA,MAC9B,KAAK,MAAM,SAAS,GAAG,OAAO,SAAS,MAAM,KAAK,GAAG,CAAC,KAAK,GAAG,OAAO;AAAA,MACrE,QAAQ,OAAO,OAAO,KAAK;AAAA,MAC3B,QAAQ,OAAO,OAAO,KAAK,KAAK;AAAA,MAChC,MAAM;AAAA,IACR,CAAC;AAAA,EACH,SAAS,KAAU;AACjB,WAAO,SAAS,IAAI,WAAW,OAAO,GAAG,CAAC;AAAA,EAC5C;AACF;;;ACxDA,IAAAC,cAAkB;AAKX,IAAM,cAAc;AAAA,EACzB,KAAK,cACF,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AACJ;AAEA,eAAsB,OAAO,OAAyB,CAAC,GAAG;AACxD,MAAI;AACF,UAAM,MAAM,kBAAkB,KAAK,GAAG;AACtC,UAAM,SAAS,MAAM,OAAO,CAAC,QAAQ,GAAG,EAAE,IAAI,CAAC;AAC/C,UAAM,OAAO;AAAA,MACX;AAAA,MACA,KAAK,GAAG,OAAO;AAAA,MACf,UAAU,OAAO;AAAA,MACjB,QAAQ,OAAO,OAAO,KAAK;AAAA,MAC3B,QAAQ,OAAO,OAAO,KAAK,KAAK;AAAA,IAClC;AACA,QAAI,CAAC,OAAO,IAAI;AACd,aAAO,SAAS,GAAG,OAAO,8BAA8B,IAAI;AAAA,IAC9D;AACA,WAAO,OAAO,EAAE,IAAI,MAAM,GAAG,KAAK,CAAC;AAAA,EACrC,SAAS,KAAU;AACjB,WAAO,SAAS,IAAI,WAAW,OAAO,GAAG,CAAC;AAAA,EAC5C;AACF;;;AChCA,IAAAC,cAAkB;AAKX,IAAM,mBAAmB;AAAA,EAC9B,KAAK,cACF,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AACJ;AAEA,eAAsB,YAAY,OAAyB,CAAC,GAAG;AAC7D,MAAI;AACF,UAAM,MAAM,kBAAkB,KAAK,GAAG;AACtC,UAAM,SAAS,MAAM,OAAO,CAAC,QAAQ,OAAO,GAAG,EAAE,IAAI,CAAC;AACtD,QAAI,CAAC,OAAO,IAAI;AACd,aAAO,SAAS,GAAG,OAAO,iBAAiB;AAAA,QACzC;AAAA,QACA,UAAU,OAAO;AAAA,QACjB,QAAQ,OAAO,OAAO,KAAK;AAAA,QAC3B,QAAQ,OAAO,OAAO,KAAK;AAAA,QAC3B,MAAM,wCAAwC,OAAO;AAAA,MACvD,CAAC;AAAA,IACH;AACA,WAAO,OAAO;AAAA,MACZ,IAAI;AAAA,MACJ;AAAA,MACA,KAAK,GAAG,OAAO;AAAA,MACf,QAAQ,OAAO,OAAO,KAAK;AAAA,MAC3B,QAAQ,OAAO,OAAO,KAAK,KAAK;AAAA,IAClC,CAAC;AAAA,EACH,SAAS,KAAU;AACjB,WAAO,SAAS,IAAI,WAAW,OAAO,GAAG,CAAC;AAAA,EAC5C;AACF;;;ACrCA,IAAAC,cAAkB;AAMX,IAAM,wBAAwB;AAAA,EACnC,OAAO,cACJ,MAAM,cAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EACvB,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,KAAK,cACF,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,OAAO,cACJ,QAAQ,EACR,SAAS,EACT,QAAQ,KAAK,EACb;AAAA,IACC;AAAA,EACF;AAAA,EACF,gBAAgB,cACb,QAAQ,EACR,SAAS,EACT,QAAQ,KAAK,EACb;AAAA,IACC;AAAA,EACF;AAAA,EACF,OAAO,cACJ,QAAQ,EACR,SAAS,EACT,QAAQ,KAAK,EACb;AAAA,IACC;AAAA,EACF;AACJ;AAMA,eAAsB,iBACpB,OAMI,CAAC,GACL;AACA,MAAI;AACF,UAAM,MAAM,kBAAkB,KAAK,GAAG;AACtC,UAAM,SAAS,KAAK,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO;AACpE,eAAW,QAAQ,OAAO;AACxB,UAAI,CAAC,eAAe,IAAI,GAAG;AACzB,eAAO,SAAS,4BAA4B,IAAI,IAAI;AAAA,MACtD;AAAA,IACF;AAEA,UAAM,UAAU,CAAC,UAAU,GAAG,OAAO,OAAO;AAC5C,QAAI,KAAK,MAAO,SAAQ,KAAK,SAAS;AACtC,QAAI,KAAK,eAAgB,SAAQ,KAAK,mBAAmB;AACzD,QAAI,KAAK,MAAO,SAAQ,KAAK,SAAS;AAEtC,UAAM,SAAS,MAAM,OAAO,SAAS,EAAE,IAAI,CAAC;AAC5C,QAAI,CAAC,OAAO,IAAI;AACd,aAAO,SAAS,GAAG,OAAO,mBAAmB;AAAA,QAC3C;AAAA,QACA;AAAA,QACA,UAAU,OAAO;AAAA,QACjB,QAAQ,OAAO,OAAO,KAAK;AAAA,QAC3B,QAAQ,OAAO,OAAO,KAAK;AAAA,QAC3B,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAEA,WAAO,OAAO;AAAA,MACZ,IAAI;AAAA,MACJ;AAAA,MACA,OAAO,MAAM,SAAS,QAAQ;AAAA,MAC9B,OAAO,QAAQ,KAAK,KAAK;AAAA,MACzB,gBAAgB,QAAQ,KAAK,cAAc;AAAA,MAC3C,OAAO,QAAQ,KAAK,KAAK;AAAA,MACzB,KAAK,CAAC,SAAS,GAAG,OAAO,EAAE,KAAK,GAAG;AAAA,MACnC,QAAQ,OAAO,OAAO,KAAK;AAAA,MAC3B,QAAQ,OAAO,OAAO,KAAK,KAAK;AAAA,MAChC,MAAM,yBAAyB,OAAO;AAAA,IACxC,CAAC;AAAA,EACH,SAAS,KAAU;AACjB,WAAO,SAAS,IAAI,WAAW,OAAO,GAAG,CAAC;AAAA,EAC5C;AACF;;;AChFO,SAAS,gBAAgB,UAAkC,CAAC,GAAc;AAC/E,QAAM,WAAW,QAAQ,aAAa;AACtC,QAAM,SAAS,uBAAuB;AAEtC,QAAM,sBAAsB;AAAA,IAC1B,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AACA,QAAM,mBAAmB;AAAA,IACvB,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAEA,MAAI,UAAU;AACZ,WAAO;AAAA,MACL;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,aACE,gDAAgD,OAAO;AAAA,QACzD,aAAa;AAAA,QACb,aAAa;AAAA,MACf;AAAA,MACA,OAAO,SAAS,cAAc,IAAI;AAAA,IACpC;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,aACE,SAAS,OAAO;AAAA,QAClB,aAAa;AAAA,QACb,aAAa;AAAA,MACf;AAAA,MACA,OAAO,SAAS,YAAY,IAAI;AAAA,IAClC;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,aACE,SAAS,OAAO;AAAA,QAClB,aAAa;AAAA,QACb,aAAa;AAAA,MACf;AAAA,MACA,OAAO,SAAS,OAAO,IAAI;AAAA,IAC7B;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,aACE,SAAS,OAAO;AAAA,QAClB,aAAa;AAAA,QACb,aAAa;AAAA,MACf;AAAA,MACA,OAAO,SAAS,eAAe,IAAI;AAAA,IACrC;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,aACE,SAAS,OAAO;AAAA,QAClB,aAAa;AAAA,QACb,aAAa;AAAA,MACf;AAAA,MACA,OAAO,SAAS,iBAAiB,IAAI;AAAA,IACvC;AAAA,EACF;AAEA,SAAO;AACT;;;AChGA,uBAAwE;AACxE,4BAA8C;;;ACAvC,IAAM,cAAc;AAapB,SAAS,qBAAqB,UAAkB,QAA4C;AACjG,SAAO;AAAA,IACL;AAAA,IACA,eAAe;AAAA,IACf,wBAAwB;AAAA,IACxB,mBAAmB;AAAA,IACnB,uBAAuB,CAAC;AAAA,IACxB,kBAAkB,CAAC;AAAA,IACnB,0BAA0B,SAAS,CAAC,QAAQ,IAAI,CAAC;AAAA,EACnD;AACF;AAEO,SAAS,gBAAgB,qBAAqC;AACnE,SAAO,6BAA6B,mBAAmB;AACzD;;;ADfA,SAAS,QAAQ,KAA2B;AAC1C,MAAI,UAAU,+BAA+B,GAAG;AAChD,MAAI,UAAU,gCAAgC,4BAA4B;AAC1E,MAAI;AAAA,IACF;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,aAAa,KAAqB,qBAAmC;AAC5E,UAAQ,GAAG;AACX,MAAI,UAAU,KAAK;AAAA,IACjB,gBAAgB;AAAA,IAChB,oBAAoB,gBAAgB,mBAAmB;AAAA,EACzD,CAAC;AACD,MAAI,IAAI,KAAK,UAAU,EAAE,OAAO,eAAe,CAAC,CAAC;AACnD;AAEA,SAAS,UAAU,KAAsB,OAAyB;AAChE,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,SAAS,IAAI,QAAQ;AAC3B,SAAO,WAAW,UAAU,KAAK;AACnC;AAEA,eAAe,SAAS,KAAwC;AAC9D,QAAM,SAAmB,CAAC;AAC1B,mBAAiB,SAAS,KAAK;AAC7B,WAAO,KAAK,OAAO,SAAS,KAAK,IAAI,QAAQ,OAAO,KAAK,KAAK,CAAC;AAAA,EACjE;AACA,QAAM,MAAM,OAAO,OAAO,MAAM,EAAE,SAAS,MAAM,EAAE,KAAK;AACxD,MAAI,CAAC,IAAK,QAAO;AACjB,SAAO,KAAK,MAAM,GAAG;AACvB;AAOO,SAAS,gBAAgB,SAAuD;AACrF,QAAM,aAAS,+BAAa,OAAO,KAAK,QAAQ;AAC9C,QAAI;AACF,YAAM,MAAM,IAAI,IAAI,IAAI,OAAO,KAAK,UAAU,IAAI,QAAQ,QAAQ,WAAW,EAAE;AAE/E,UAAI,IAAI,WAAW,WAAW;AAC5B,gBAAQ,GAAG;AACX,YAAI,UAAU,GAAG;AACjB,YAAI,IAAI;AACR;AAAA,MACF;AAEA,UAAI,IAAI,aAAa,OAAO,IAAI,WAAW,OAAO;AAChD,gBAAQ,GAAG;AACX,YAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,YAAI;AAAA,UACF,KAAK,UAAU;AAAA,YACb,IAAI;AAAA,YACJ,MAAM;AAAA,YACN,SAAS;AAAA,YACT,WAAW;AAAA,YACX,KAAK;AAAA,YACL,UAAU,CAAC,QAAQ;AAAA,UACrB,CAAC;AAAA,QACH;AACA;AAAA,MACF;AAEA,UAAI,IAAI,aAAa,2CAA2C,IAAI,WAAW,OAAO;AACpF,gBAAQ,GAAG;AACX,YAAI,UAAU,KAAK,EAAE,gBAAgB,kCAAkC,CAAC;AACxE,YAAI;AAAA,UACF,KAAK;AAAA,YACH,qBAAqB,IAAI,IAAI,QAAQ,IAAI,MAAM,EAAE,MAAM,QAAQ,QAAQ,SAAS,CAAC;AAAA,UACnF;AAAA,QACF;AACA;AAAA,MACF;AAEA,UAAI,IAAI,aAAa,QAAQ;AAC3B,gBAAQ,GAAG;AACX,YAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,YAAI,IAAI,KAAK,UAAU,EAAE,OAAO,mCAAmC,CAAC,CAAC;AACrE;AAAA,MACF;AAEA,UAAI,CAAC,UAAU,KAAK,QAAQ,SAAS,GAAG;AACtC,qBAAa,KAAK,IAAI,IAAI,yCAAyC,IAAI,MAAM,EAAE,IAAI;AACnF;AAAA,MACF;AAEA,cAAQ,GAAG;AACX,YAAM,MAAM,gBAAgB,EAAE,UAAU,CAAC,QAAQ,SAAS,CAAC;AAC3D,YAAM,YAAY,IAAI,oDAA8B;AAAA,QAClD,oBAAoB;AAAA,MACtB,CAAC;AACD,YAAM,IAAI,QAAQ,SAAS;AAC3B,YAAM,aAAa,IAAI,WAAW,SAAS,MAAM,SAAS,GAAG,IAAI;AACjE,YAAM,UAAU,cAAc,KAAK,KAAK,UAAU;AAAA,IACpD,SAAS,KAAK;AACZ,cAAQ,MAAM,GAAG,WAAW,gBAAgB,GAAG;AAC/C,UAAI,CAAC,IAAI,aAAa;AACpB,YAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AAAA,MAC3D;AACA,UAAI,CAAC,IAAI,eAAe;AACtB,YAAI,IAAI,KAAK,UAAU,EAAE,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EAAE,CAAC,CAAC;AAAA,MACrF;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO,OAAO,QAAQ,MAAM,QAAQ,MAAM,MAAM;AAC9C,UAAM,OAAO,OAAO,QAAQ;AAC5B,UAAM,OAAO,OAAO,SAAS,YAAY,OAAO,KAAK,OAAO,QAAQ;AACpE,YAAQ;AAAA,MACN,GAAG,WAAW,KAAK,eAAe,8BAA8B,QAAQ,IAAI,IAAI,IAAI,UACjF,QAAQ,WAAW,yBAAyB;AAAA,IACjD;AAAA,EACF,CAAC;AACD,SAAO;AACT;;;ArBtHA,SAAS,UAAU,MAKjB;AACA,MAAI,OACF,KAAK,SAAS,QAAQ,KACtB,QAAQ,IAAI,iBAAiB,OAC7B,QAAQ,IAAI,qBAAqB;AACnC,MAAI,WACF,KAAK,SAAS,aAAa,KAC3B,QAAQ,IAAI,sBAAsB,OAClC,QAAQ,IAAI,0BAA0B;AACxC,MAAI,OAAO,OAAO,QAAQ,IAAI,QAAQ,QAAQ,IAAI,gBAAgB,QAAQ,IAAI,oBAAoB,IAAI;AACtG,MAAI,OAAO,QAAQ,IAAI,gBAAgB,QAAQ,IAAI,qBAAqB,OAAO,cAAc;AAC7F,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,MAAM,KAAK,CAAC;AAClB,QAAI,QAAQ,YAAY,KAAK,IAAI,CAAC,GAAG;AACnC,aAAO,OAAO,KAAK,EAAE,CAAC,CAAC;AAAA,IACzB,WAAW,KAAK,WAAW,SAAS,GAAG;AACrC,aAAO,OAAO,IAAI,MAAM,UAAU,MAAM,CAAC;AAAA,IAC3C,WAAW,QAAQ,YAAY,KAAK,IAAI,CAAC,GAAG;AAC1C,aAAO,KAAK,EAAE,CAAC;AAAA,IACjB,WAAW,KAAK,WAAW,SAAS,GAAG;AACrC,aAAO,IAAI,MAAM,UAAU,MAAM;AAAA,IACnC;AAAA,EACF;AACA,MAAI,CAAC,OAAO,SAAS,IAAI,KAAK,QAAQ,EAAG,QAAO;AAChD,SAAO,EAAE,MAAM,UAAU,MAAM,KAAK;AACtC;AAEA,eAAe,OAAO;AACpB,QAAM,OAAO,UAAU,QAAQ,KAAK,MAAM,CAAC,CAAC;AAC5C,MAAI,KAAK,MAAM;AACb,oBAAgB;AAAA,MACd,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,MACX,UAAU,KAAK;AAAA,MACf,WACE,QAAQ,IAAI,oBAAoB,KAAK,KACrC,QAAQ,IAAI,wBAAwB,KAAK,KACzC;AAAA,IACJ,CAAC;AACD;AAAA,EACF;AAEA,QAAM,SAAS,gBAAgB,EAAE,UAAU,KAAK,CAAC;AACjD,QAAM,YAAY,IAAI,kCAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAC9B,UAAQ,MAAM,GAAG,WAAW,KAAK,eAAe,iBAAiB;AACnE;AAEA,KAAK,EAAE,MAAM,CAAC,QAAQ;AACpB,UAAQ,MAAM,GAAG,WAAW,qBAAqB,GAAG;AACpD,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["import_mcp","import_zod","import_zod","import_zod","CATEGORIES","import_zod","fs","path","import_zod","import_zod","import_zod","import_zod"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/catalog.ts","../src/resources.ts","../src/registry.ts","../src/utf8.ts","../src/tools/get-component.ts","../src/brand.ts","../src/install-hint.ts","../src/result.ts","../src/tools/list-components.ts","../src/tools/search-components.ts","../src/aliases.ts","../package.json","../src/version.ts","../src/elicit.ts","../src/tools/add-components.ts","../src/cli.ts","../src/cli-report.ts","../src/tools/diff-components.ts","../src/tools/doctor.ts","../src/tools/init-project.ts","../src/tools/update-components.ts","../src/server.ts","../src/http.ts","../src/auth-metadata.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * ply-ui-mcp — MCP server wrapping the Ply registry + CLI.\n *\n * Default: stdio (Cursor, Claude Code/Desktop, Kimi, VS Code, Windsurf).\n * `--http`: Streamable HTTP for ChatGPT / Gemini chat apps and remote MCP URLs.\n * Hosted HTTP should use `--read-only` so catalog tools work without a local project.\n */\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { createMcpServer, PACKAGE_VERSION } from './server';\nimport { startHttpServer } from './http';\nimport { MCP_PACKAGE } from './brand';\n\nfunction parseArgs(argv: string[]): {\n http: boolean;\n readOnly: boolean;\n port: number;\n host: string;\n} {\n let http =\n argv.includes('--http') ||\n process.env.PLY_MCP_HTTP === '1' ||\n process.env.BASE_UI_MCP_HTTP === '1';\n let readOnly =\n argv.includes('--read-only') ||\n process.env.PLY_MCP_READ_ONLY === '1' ||\n process.env.BASE_UI_MCP_READ_ONLY === '1';\n let port = Number(process.env.PORT || process.env.PLY_MCP_PORT || process.env.BASE_UI_MCP_PORT || 3334);\n let host = process.env.PLY_MCP_HOST || process.env.BASE_UI_MCP_HOST || (http ? '127.0.0.1' : '127.0.0.1');\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg === '--port' && argv[i + 1]) {\n port = Number(argv[++i]);\n } else if (arg?.startsWith('--port=')) {\n port = Number(arg.slice('--port='.length));\n } else if (arg === '--host' && argv[i + 1]) {\n host = argv[++i]!;\n } else if (arg?.startsWith('--host=')) {\n host = arg.slice('--host='.length);\n }\n }\n if (!Number.isFinite(port) || port <= 0) port = 3334;\n return { http, readOnly, port, host };\n}\n\nasync function main() {\n const opts = parseArgs(process.argv.slice(2));\n if (opts.http) {\n startHttpServer({\n host: opts.host,\n port: opts.port,\n readOnly: opts.readOnly,\n authToken:\n process.env.PLY_MCP_AUTH_TOKEN?.trim() ||\n process.env.BASE_UI_MCP_AUTH_TOKEN?.trim() ||\n undefined,\n });\n return;\n }\n\n const server = createMcpServer({ mutating: true });\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error(`${MCP_PACKAGE} v${PACKAGE_VERSION} ready on stdio`);\n}\n\nmain().catch((err) => {\n console.error(`${MCP_PACKAGE} failed to start:`, err);\n process.exit(1);\n});\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { registerResources } from './resources';\nimport { getComponent, getComponentInput } from './tools/get-component';\nimport { listComponents, listComponentsInput } from './tools/list-components';\nimport { searchComponents, searchComponentsInput } from './tools/search-components';\nimport { PACKAGE_VERSION } from './version';\nimport { CLI_NPX, MCP_SERVER_NAME } from './brand';\n\n/**\n * One instructions string for every Ply server. Hosted catalog and local\n * install share it. It is not a second llms.txt.\n */\nexport const SERVER_INSTRUCTIONS =\n 'Search the catalog before inventing a component name. The hosted catalog cannot write files. A local install is init_project, then add_components. When PLY_LICENSE_KEY is already set, leave it in the environment and out of the tool call.';\n\n/** ChatGPT treats tools as writes unless readOnlyHint is set. */\nconst catalogAnnotations = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n} as const;\n\n/** Catalog-only server: safe to bundle on Cloudflare Workers (no child_process). */\nexport function createCatalogMcpServer(): McpServer {\n const server = new McpServer(\n {\n name: MCP_SERVER_NAME,\n version: PACKAGE_VERSION,\n },\n { instructions: SERVER_INSTRUCTIONS },\n );\n\n server.registerTool(\n 'list_components',\n {\n title: 'List Ply components',\n description:\n `List components from the Ply registry. Filter by tier (free|pro|all), category, or name substring. Does not install anything. To copy a component into a project, tell the user to run ${CLI_NPX} add <name>.`,\n inputSchema: listComponentsInput,\n annotations: catalogAnnotations,\n },\n async (args) => listComponents(args)\n );\n\n server.registerTool(\n 'get_component',\n {\n title: 'Get component details',\n description:\n `Get registry metadata for one component (deps, category, file list). Free source only when includeSource=true. Pro source is never streamed via MCP. Does not install; returns installCommand (${CLI_NPX} add <name>).`,\n inputSchema: getComponentInput,\n annotations: catalogAnnotations,\n },\n async (args) => getComponent(args)\n );\n\n server.registerTool(\n 'search_components',\n {\n title: 'Search Ply components',\n description:\n `Fuzzy / token search over registry component names (e.g. \"dialog\", \"sheet\", \"carousel\"). Does not install anything. Prefer this before guessing names, then give the user ${CLI_NPX} add <name> (or local stdio add_components).`,\n inputSchema: searchComponentsInput,\n annotations: catalogAnnotations,\n },\n async (args) => searchComponents(args)\n );\n\n registerResources(server);\n return server;\n}\n","import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport {\n SITE_URL,\n fetchFreeItem,\n fetchIndex,\n fetchText,\n isSafeItemName,\n} from './registry';\nimport { utf8ByteLength } from './utf8';\n\nexport function registerResources(server: McpServer) {\n server.registerResource(\n 'registry-index',\n 'ply-ui://registry/index',\n {\n title: 'Registry index',\n description: 'Public Ply registry index (names, tiers, categories, description, usage, keywords, deps)',\n mimeType: 'application/json',\n },\n async (uri) => {\n const index = await fetchIndex();\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify(index, null, 2),\n },\n ],\n };\n }\n );\n\n server.registerResource(\n 'docs-llms',\n 'ply-ui://docs/llms',\n {\n title: 'llms.txt',\n description:\n 'Agent-oriented product overview (keep fetching this URL even when MCP is available)',\n mimeType: 'text/plain',\n },\n async (uri) => {\n const text = await fetchText(`${SITE_URL}/llms.txt`);\n return {\n contents: [{ uri: uri.href, mimeType: 'text/plain', text }],\n };\n }\n );\n\n server.registerResource(\n 'docs-catalog',\n 'ply-ui://docs/catalog',\n {\n title: 'AI component catalog',\n description: 'docs/ai/components.md — detailed component reference for agents',\n mimeType: 'text/markdown',\n },\n async (uri) => {\n const text = await fetchText(`${SITE_URL}/docs/ai/components.md`);\n return {\n contents: [{ uri: uri.href, mimeType: 'text/markdown', text }],\n };\n }\n );\n\n server.registerResource(\n 'docs-cursor-rules',\n 'ply-ui://docs/cursor-rules',\n {\n title: 'Cursor / Windsurf project rules',\n description:\n 'Save as .cursor/rules/ply-ui.mdc (or .windsurf/rules/ply-ui.md). Teaches assistants to write standalone zoneless Angular 22 with Ply without running MCP.',\n mimeType: 'text/markdown',\n },\n async (uri) => {\n const text = await fetchText(`${SITE_URL}/docs/ai/ply-ui.mdc`);\n return {\n contents: [{ uri: uri.href, mimeType: 'text/markdown', text }],\n };\n }\n );\n\n server.registerResource(\n 'docs-snippets',\n 'ply-ui://docs/snippets',\n {\n title: 'VS Code / Cursor snippets',\n description:\n 'Save as .vscode/ply-ui.code-snippets. Prefixes like ply-card expand usage markup after CLI install.',\n mimeType: 'application/json',\n },\n async (uri) => {\n const text = await fetchText(`${SITE_URL}/docs/ai/ply-ui.code-snippets`);\n return {\n contents: [{ uri: uri.href, mimeType: 'application/json', text }],\n };\n }\n );\n\n server.registerResource(\n 'component',\n new ResourceTemplate('ply-ui://component/{name}', {\n list: undefined,\n }),\n {\n title: 'Component metadata',\n description:\n 'Registry metadata for one component. Free source files are listed without content; Pro never streams source via MCP in V1.',\n mimeType: 'application/json',\n },\n async (uri, vars) => {\n const name = String(vars.name || '');\n if (!isSafeItemName(name)) {\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify({ error: `Invalid name: ${name}` }),\n },\n ],\n };\n }\n const index = await fetchIndex();\n const entry = index.find((i) => i.name === name);\n if (!entry) {\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify({ error: `Unknown component: ${name}` }),\n },\n ],\n };\n }\n\n if (entry.tier === 'pro') {\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify(\n {\n ...entry,\n files: null,\n note: `Pro — metadata only. ${SITE_URL}/pricing`,\n },\n null,\n 2\n ),\n },\n ],\n };\n }\n\n const item = await fetchFreeItem(name);\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify(\n {\n name: item.name,\n tier: item.tier,\n category: item.category,\n description: item.description,\n usage: item.usage,\n keywords: item.keywords,\n dependencies: item.dependencies,\n registryDependencies: item.registryDependencies,\n files: item.files.map((f) => ({\n path: f.name,\n bytes: utf8ByteLength(f.content),\n })),\n },\n null,\n 2\n ),\n },\n ],\n };\n }\n );\n}\n","/**\n * Thin registry client — mirrors packages/cli/src/registry.ts URLs/schemas\n * so the MCP server can return structured JSON without parsing CLI stdout.\n * Install/write side effects still go through ply-ui-cli (canonical path).\n */\nimport { z } from 'zod';\n\nexport const SITE_URL = 'https://ply-ui.com';\nexport const GITHUB_HUB_URL = 'https://github.com/ply-ui-ng/ply';\n\nconst env =\n typeof process !== 'undefined' && process.env ? process.env : ({} as Record<string, string | undefined>);\n\nfunction firstEnv(...names: string[]): string | undefined {\n for (const name of names) {\n const v = env[name]?.trim();\n if (v) return v;\n }\n}\n\nexport const FREE_REGISTRY_URL =\n firstEnv('PLY_REGISTRY_URL', 'BASE_UI_REGISTRY_URL') || `${SITE_URL}/registry`;\n\nexport const PRO_REGISTRY_URL =\n firstEnv('PLY_PRO_REGISTRY_URL', 'BASE_UI_PRO_REGISTRY_URL') ||\n 'https://pro.ply-ui.com/registry';\n\nconst registryFileSchema = z.object({\n name: z.string(),\n content: z.string(),\n});\n\nexport const registryItemSchema = z.object({\n name: z.string(),\n tier: z.enum(['free', 'pro']),\n category: z\n .enum(['application', 'page-layout', 'block', 'widget', 'shell', 'component'])\n .optional()\n .default('component'),\n dependencies: z.array(z.string()).default([]),\n registryDependencies: z.array(z.string()).default([]),\n description: z.string().optional().default(''),\n usage: z.string().optional().default(''),\n keywords: z.array(z.string()).optional().default([]),\n files: z.array(registryFileSchema),\n type: z.string().optional(),\n license: z.enum(['MIT', 'Ply Pro']).optional(),\n});\n\nexport const registryIndexSchema = z.array(registryItemSchema.omit({ files: true }));\n\nexport type RegistryItem = z.infer<typeof registryItemSchema>;\nexport type RegistryIndexEntry = z.infer<typeof registryIndexSchema>[number];\n\nexport type Category = NonNullable<RegistryIndexEntry['category']>;\n\nexport function itemLicense(tier: 'free' | 'pro'): 'MIT' | 'Ply Pro' {\n return tier === 'pro' ? 'Ply Pro' : 'MIT';\n}\n\nexport function hubSourceUrl(name: string): string {\n return `${GITHUB_HUB_URL}/tree/main/components/${name}`;\n}\n\nexport function itemHaystack(\n item: Pick<RegistryIndexEntry, 'name' | 'description' | 'usage' | 'keywords'>\n): string {\n return [item.name, item.description, item.usage, ...(item.keywords ?? [])]\n .filter(Boolean)\n .join(' ')\n .toLowerCase();\n}\n\nexport function isSafeItemName(name: string): boolean {\n return /^[a-z0-9][a-z0-9-.]*$/i.test(name) && !name.includes('..');\n}\n\nasync function fetchJson(url: string, headers: Record<string, string> = {}): Promise<unknown> {\n let res: Response;\n try {\n res = await fetch(url, { headers });\n } catch (err: any) {\n throw new Error(\n `Network error while contacting the registry (${err.message}). Check your connection and try again.`\n );\n }\n if (res.status === 401 || res.status === 403) {\n throw new Error(\n `License rejected (HTTP ${res.status}). Check PLY_LICENSE_KEY, or see ${SITE_URL}/pricing.`\n );\n }\n if (res.status === 404) {\n const e: any = new Error('Not found');\n e.code = 'NOT_FOUND';\n throw e;\n }\n if (!res.ok) {\n throw new Error(`Registry request failed (HTTP ${res.status}) for ${url}.`);\n }\n return res.json();\n}\n\nexport async function fetchIndex(): Promise<RegistryIndexEntry[]> {\n const data = await fetchJson(`${FREE_REGISTRY_URL}/index.json`);\n return registryIndexSchema.parse(data);\n}\n\n/** Free registry item only — V1 never streams Pro source through MCP. */\nexport async function fetchFreeItem(name: string): Promise<RegistryItem> {\n if (!isSafeItemName(name)) {\n throw new Error(`Invalid component name: '${name}'.`);\n }\n const data = await fetchJson(`${FREE_REGISTRY_URL}/styles/default/${name}.json`);\n return registryItemSchema.parse(data);\n}\n\nexport async function fetchText(url: string): Promise<string> {\n let res: Response;\n try {\n res = await fetch(url);\n } catch (err: any) {\n throw new Error(`Network error fetching ${url}: ${err.message}`);\n }\n if (!res.ok) {\n throw new Error(`Failed to fetch ${url} (HTTP ${res.status}).`);\n }\n return res.text();\n}\n\n/** Closest names to `query`, for search / suggestions. */\nexport function suggestNames(query: string, names: string[], limit = 8): string[] {\n const q = query.toLowerCase().trim();\n if (!q) return [];\n const scored = names\n .map((name) => {\n const n = name.toLowerCase();\n let score: number;\n if (n === q) score = 0;\n else if (n.startsWith(q) || q.startsWith(n)) score = 1;\n else if (n.includes(q) || q.includes(n)) score = 2;\n else score = 3 + levenshtein(q, n);\n return { name, score };\n })\n .filter((s) => s.score <= 6)\n .sort((a, b) => a.score - b.score || a.name.localeCompare(b.name));\n return scored.slice(0, limit).map((s) => s.name);\n}\n\nfunction levenshtein(a: string, b: string): number {\n const m = a.length;\n const n = b.length;\n if (!m) return n;\n if (!n) return m;\n let prev = Array.from({ length: n + 1 }, (_, i) => i);\n for (let i = 1; i <= m; i++) {\n const curr = [i];\n for (let j = 1; j <= n; j++) {\n curr[j] = Math.min(\n prev[j] + 1,\n curr[j - 1] + 1,\n prev[j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1)\n );\n }\n prev = curr;\n }\n return prev[n];\n}\n","/** UTF-8 byte length without Node `Buffer` (Workers / browsers). */\nexport function utf8ByteLength(text: string): number {\n return new TextEncoder().encode(text).byteLength;\n}\n","import { z } from 'zod';\nimport {\n SITE_URL,\n fetchFreeItem,\n fetchIndex,\n hubSourceUrl,\n isSafeItemName,\n itemLicense,\n suggestNames,\n} from '../registry';\nimport { cliAddCommand, installHint } from '../install-hint';\nimport { failJson, okJson } from '../result';\nimport { utf8ByteLength } from '../utf8';\n\nexport const getComponentInput = {\n name: z.string().describe('Registry component name (e.g. button, card)'),\n includeSource: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'If true, include free-tier source file contents. Pro source is never returned via MCP in V1.'\n ),\n};\n\nexport async function getComponent(args: { name: string; includeSource?: boolean }) {\n try {\n const name = args.name.trim();\n if (!isSafeItemName(name)) {\n return failJson(`Invalid component name: '${name}'.`);\n }\n\n const index = await fetchIndex();\n const entry = index.find((i) => i.name === name);\n if (!entry) {\n const suggestions = suggestNames(\n name,\n index.map((i) => i.name)\n );\n return failJson(`Unknown component: '${name}'.`, {\n suggestions,\n listHint: 'Call list_components or search_components.',\n });\n }\n\n const base = {\n ok: true as const,\n name: entry.name,\n tier: entry.tier,\n license: entry.license || itemLicense(entry.tier),\n category: entry.category || 'component',\n description: entry.description || '',\n usage: entry.usage || '',\n keywords: entry.keywords || [],\n dependencies: entry.dependencies,\n registryDependencies: entry.registryDependencies,\n docsUrl: `${SITE_URL}/base-elements/${entry.name}/`,\n pricingUrl: `${SITE_URL}/pricing`,\n };\n\n if (entry.tier === 'pro') {\n return okJson({\n ...base,\n source: null,\n sourceUrl: null,\n installCommand: cliAddCommand(name),\n note: `Pro component — metadata only. ${installHint(name)} Pro install also needs PLY_LICENSE_KEY. Buy at ${SITE_URL}/pricing.`,\n });\n }\n\n const item = await fetchFreeItem(name);\n const files = item.files.map((f) => ({\n path: f.name,\n bytes: utf8ByteLength(f.content),\n ...(args.includeSource ? { content: f.content } : {}),\n }));\n\n return okJson({\n ...base,\n files,\n includeSource: Boolean(args.includeSource),\n sourceUrl: hubSourceUrl(name),\n installCommand: cliAddCommand(name),\n note: args.includeSource\n ? `Free source included for reading. ${installHint(name)}`\n : `Source omitted by default. Pass includeSource=true to read free files here. ${installHint(name)}`,\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","/** Public npm / npx names for the Ply CLI and MCP. */\nexport const CLI_PACKAGE = 'ply-ui-cli';\nexport const CLI_BIN = 'ply-ui-cli';\nexport const CLI_NPX = `npx ${CLI_BIN}`;\nexport const MCP_PACKAGE = 'ply-ui-mcp';\nexport const MCP_NPX = `npx -y ${MCP_PACKAGE}`;\nexport const MCP_SERVER_NAME = 'ply';\n","import { CLI_NPX } from './brand';\n\n/** Copy-paste installer. Hosted catalog MCP cannot write files. */\nexport function cliAddCommand(name?: string): string {\n return name?.trim()\n ? `${CLI_NPX} add ${name.trim()}`\n : `${CLI_NPX} add <name>`;\n}\n\nexport function installHint(name?: string): string {\n return (\n `This catalog does not write files. Install in the project with \\`${cliAddCommand(name)}\\`. ` +\n 'Local stdio MCP (Cursor, Claude Code) can call add_components instead.'\n );\n}\n","import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\n\nfunction asRecord(data: unknown): Record<string, unknown> | undefined {\n if (data && typeof data === 'object' && !Array.isArray(data)) {\n return data as Record<string, unknown>;\n }\n return undefined;\n}\n\nexport function okJson(data: unknown): CallToolResult {\n const structuredContent = asRecord(data);\n return {\n content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],\n ...(structuredContent ? { structuredContent } : {}),\n };\n}\n\nexport function failJson(\n message: string,\n extra: Record<string, unknown> = {}\n): CallToolResult {\n const structuredContent = { ok: false, error: message, ...extra };\n return {\n isError: true,\n structuredContent,\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n };\n}\n","import { z } from 'zod';\nimport { fetchIndex, itemHaystack, itemLicense, type Category } from '../registry';\nimport { installHint } from '../install-hint';\nimport { failJson, okJson } from '../result';\n\nconst CATEGORIES = [\n 'application',\n 'page-layout',\n 'block',\n 'widget',\n 'shell',\n 'component',\n] as const satisfies readonly Category[];\n\nexport const listComponentsInput = {\n tier: z\n .enum(['free', 'pro', 'all'])\n .optional()\n .default('all')\n .describe('Filter by license tier'),\n category: z\n .enum(CATEGORIES)\n .optional()\n .describe('Filter by registry category'),\n q: z\n .string()\n .optional()\n .describe('Substring filter on name, description, usage, or keywords (case-insensitive)'),\n};\n\nexport async function listComponents(args: {\n tier?: 'free' | 'pro' | 'all';\n category?: Category;\n q?: string;\n}) {\n try {\n const index = await fetchIndex();\n const tier = args.tier ?? 'all';\n const q = args.q?.trim().toLowerCase();\n\n let items = index;\n if (tier !== 'all') {\n items = items.filter((i) => i.tier === tier);\n }\n if (args.category) {\n items = items.filter((i) => (i.category || 'component') === args.category);\n }\n if (q) {\n items = items.filter((i) => itemHaystack(i).includes(q));\n }\n\n items = [...items].sort((a, b) => a.name.localeCompare(b.name));\n\n return okJson({\n ok: true,\n count: items.length,\n items: items.map((i) => ({\n name: i.name,\n tier: i.tier,\n license: i.license || itemLicense(i.tier),\n category: i.category || 'component',\n description: i.description || '',\n usage: i.usage || '',\n keywords: i.keywords || [],\n dependencies: i.dependencies,\n registryDependencies: i.registryDependencies,\n })),\n hint: `Use get_component for details. ${installHint()}`,\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","import { z } from 'zod';\nimport { canonicalComponentName } from '../aliases';\nimport { fetchIndex, itemHaystack, suggestNames, itemLicense, type Category } from '../registry';\nimport { installHint } from '../install-hint';\nimport { failJson, okJson } from '../result';\n\nconst CATEGORIES = [\n 'application',\n 'page-layout',\n 'block',\n 'widget',\n 'shell',\n 'component',\n] as const satisfies readonly Category[];\n\nexport const searchComponentsInput = {\n query: z\n .string()\n .min(1)\n .describe('Natural-language or substring query (e.g. \"dialog modal\", \"button\"). Matches name, description, usage, and keywords.'),\n tier: z\n .enum(['free', 'pro', 'all'])\n .optional()\n .default('all')\n .describe('Filter by license tier'),\n category: z.enum(CATEGORIES).optional().describe('Filter by registry category'),\n limit: z.number().int().min(1).max(40).optional().default(12),\n};\n\nfunction tokenize(query: string): string[] {\n return query\n .toLowerCase()\n .split(/[^a-z0-9]+/i)\n .map((t) => t.trim())\n .filter((t) => t.length >= 2);\n}\n\nexport async function searchComponents(args: {\n query: string;\n tier?: 'free' | 'pro' | 'all';\n category?: Category;\n limit?: number;\n}) {\n try {\n const index = await fetchIndex();\n const tier = args.tier ?? 'all';\n const limit = args.limit ?? 12;\n const rawQuery = args.query.trim();\n const canonical = canonicalComponentName(rawQuery);\n const variants = [...new Set([rawQuery, canonical].filter(Boolean))];\n\n let pool = index;\n if (tier !== 'all') {\n pool = pool.filter((i) => i.tier === tier);\n }\n if (args.category) {\n pool = pool.filter((i) => (i.category || 'component') === args.category);\n }\n\n const names = pool.map((i) => i.name);\n const byFuzzy = new Set(variants.flatMap((q) => suggestNames(q, names, limit)));\n\n const byTokens = pool.filter((i) => {\n const hay = itemHaystack(i);\n return variants.some((q) => {\n const tokens = tokenize(q);\n return tokens.length > 0 && tokens.every((t) => hay.includes(t));\n });\n });\n\n const ranked = [\n ...byTokens.sort((a, b) => a.name.localeCompare(b.name)),\n ...pool\n .filter((i) => byFuzzy.has(i.name) && !byTokens.some((t) => t.name === i.name))\n .sort(\n (a, b) =>\n [...byFuzzy].indexOf(a.name) - [...byFuzzy].indexOf(b.name)\n ),\n ].slice(0, limit);\n\n return okJson({\n ok: true,\n query: args.query,\n count: ranked.length,\n matches: ranked.map((i) => ({\n name: i.name,\n tier: i.tier,\n license: i.license || itemLicense(i.tier),\n category: i.category || 'component',\n description: i.description || '',\n usage: i.usage || '',\n keywords: i.keywords || [],\n registryDependencies: i.registryDependencies,\n })),\n hint: `Next: get_component for details. ${installHint()}`,\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","/** Keep in sync with packages/cli/src/aliases.ts */\nexport const COMPONENT_ALIASES: Record<string, string> = {\n sheet: 'drawer',\n 'side-sheet': 'drawer',\n gallery: 'slider',\n 'image-slider': 'slider',\n slideshow: 'slider',\n range: 'range-slider',\n 'slider-input': 'range-slider',\n 'input-slider': 'range-slider',\n 'base-list-item': 'ply-list-item',\n 'base-tab-icon': 'ply-tab-icon',\n 'base-group-button': 'ply-group-button',\n 'base-dropdown-menu-item': 'ply-dropdown-menu-item',\n 'base-context-menu-item': 'ply-context-menu-item',\n};\n\nexport function canonicalComponentName(name: string): string {\n const key = name.trim().toLowerCase();\n return COMPONENT_ALIASES[key] ?? name.trim();\n}\n","{\n \"name\": \"ply-ui-mcp\",\n \"version\": \"0.1.32\",\n \"description\": \"Ply MCP server — stdio or Streamable HTTP (--http). List, search, init, doctor, diff, update, and add Angular + Tailwind components (Pro with PLY_LICENSE_KEY). Not MUI Base UI.\",\n \"type\": \"commonjs\",\n \"main\": \"dist/index.js\",\n \"bin\": {\n \"ply-ui-mcp\": \"dist/index.js\"\n },\n \"files\": [\n \"dist\",\n \"README.md\",\n \"LICENSE\"\n ],\n \"engines\": {\n \"node\": \">=18\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"start\": \"node dist/index.js\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run\",\n \"prepublishOnly\": \"npm run build\"\n },\n \"keywords\": [\n \"mcp\",\n \"model-context-protocol\",\n \"angular\",\n \"tailwindcss\",\n \"ply\",\n \"ply-ui\",\n \"ply-ui-mcp\",\n \"cli\"\n ],\n \"author\": \"Lussos\",\n \"license\": \"MIT\",\n \"mcpName\": \"io.github.ply-ui-ng/ply-ui\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/ply-ui-ng/ply.git\",\n \"directory\": \"packages/mcp\"\n },\n \"homepage\": \"https://ply-ui.com\",\n \"bugs\": {\n \"url\": \"https://github.com/ply-ui-ng/ply/issues\"\n },\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org/\"\n },\n \"dependencies\": {\n \"@modelcontextprotocol/sdk\": \"^1.32.1\",\n \"zod\": \"^4.6.2\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^26.5.1\",\n \"tsup\": \"^9.0.0\",\n \"typescript\": \"^7.0.2\",\n \"vitest\": \"^5.0.0\"\n },\n \"overrides\": {\n \"esbuild\": \"0.28.2\",\n \"fast-uri\": \"3.1.8\",\n \"proxy-addr\": \"2.0.8\",\n \"hono\": \"4.13.13\",\n \"qs\": \"6.16.0\"\n }\n}\n","import packageJson from '../package.json' with { type: 'json' };\n\n/** Bundled from packages/mcp/package.json by tsup and by the Workers deploy. */\nexport const PACKAGE_VERSION: string = packageJson.version;\n","import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\n\nexport type ReplaceDecision = 'replace' | 'keep' | 'unsupported';\n\nexport interface ReplaceResolution {\n apply: boolean;\n confirmation?: 'accepted' | 'declined' | 'unsupported';\n}\n\n/**\n * Ask a host that supports form elicitation before an overwrite.\n * Hosts that cannot ask leave the explicit flag in place.\n */\nexport async function confirmReplace(server: McpServer, message: string): Promise<ReplaceDecision> {\n try {\n const result = await server.server.elicitInput({\n mode: 'form',\n message,\n requestedSchema: {\n type: 'object',\n properties: {\n replace: {\n type: 'boolean',\n title: 'Replace existing files',\n description: 'Overwrite the copies already in the project.',\n default: false,\n },\n },\n required: ['replace'],\n },\n });\n if (result.action === 'accept' && result.content?.replace === true) return 'replace';\n return 'keep';\n } catch (err) {\n const text = err instanceof Error ? err.message : String(err);\n if (text.includes('does not support form elicitation')) return 'unsupported';\n throw err;\n }\n}\n\nexport async function resolveReplace(\n requested: boolean,\n confirm: ((message: string) => Promise<ReplaceDecision>) | undefined,\n message: string,\n): Promise<ReplaceResolution> {\n if (!requested) return { apply: false };\n if (!confirm) return { apply: true };\n const decision = await confirm(message);\n if (decision === 'keep') return { apply: false, confirmation: 'declined' };\n if (decision === 'unsupported') return { apply: true, confirmation: 'unsupported' };\n return { apply: true, confirmation: 'accepted' };\n}\n","import { z } from 'zod';\nimport { resolveProjectCwd, runCli } from '../cli';\nimport {\n SITE_URL,\n fetchIndex,\n isSafeItemName,\n suggestNames,\n} from '../registry';\nimport { addOutput, parseAddReport } from '../cli-report';\nimport { resolveReplace, type ReplaceDecision } from '../elicit';\nimport { failJson, okJson } from '../result';\nimport { canonicalComponentName } from '../aliases';\nimport { CLI_BIN, CLI_NPX } from '../brand';\n\nexport { addOutput };\n\nexport interface AddComponentsHooks {\n confirmReplace?: (message: string) => Promise<ReplaceDecision>;\n}\n\nexport const addComponentsInput = {\n names: z\n .array(z.string().min(1))\n .min(1)\n .describe('One or more registry component names to install (aliases like sheet → drawer are resolved)'),\n cwd: z\n .string()\n .optional()\n .describe(\n 'Project root containing ply-ui.json (defaults to MCP process cwd / PLY_CWD / BASE_UI_CWD)'\n ),\n overwrite: z\n .boolean()\n .optional()\n .default(false)\n .describe('Overwrite existing component folders (maps to CLI --overwrite)'),\n licenseKey: z\n .string()\n .optional()\n .describe(\n 'Ply Pro license. Prefer PLY_LICENSE_KEY (or BASE_UI_LICENSE_KEY) in the MCP server env instead of putting a key in chat.'\n ),\n};\n\n/**\n * Installs registry components via the CLI. Pro names require\n * `licenseKey` or `PLY_LICENSE_KEY` / `BASE_UI_LICENSE_KEY`.\n */\nexport async function addComponents(\n args: {\n names: string[];\n cwd?: string;\n overwrite?: boolean;\n licenseKey?: string;\n },\n hooks: AddComponentsHooks = {},\n) {\n try {\n const cwd = resolveProjectCwd(args.cwd);\n const names = [\n ...new Set(\n args.names\n .map((n) => canonicalComponentName(n.trim()))\n .filter(Boolean)\n ),\n ];\n\n if (!names.length) {\n return failJson('Provide at least one component name.');\n }\n\n for (const name of names) {\n if (!isSafeItemName(name)) {\n return failJson(`Invalid component name: '${name}'.`);\n }\n }\n\n const index = await fetchIndex();\n const byName = new Map(index.map((i) => [i.name, i]));\n const unknown: string[] = [];\n const pro: string[] = [];\n const free: string[] = [];\n\n for (const name of names) {\n const entry = byName.get(name);\n if (!entry) {\n unknown.push(name);\n continue;\n }\n if (entry.tier === 'pro') {\n pro.push(name);\n } else {\n free.push(name);\n }\n }\n\n if (unknown.length) {\n return failJson('Unknown component name(s).', {\n unknown,\n suggestions: unknown.flatMap((n) =>\n suggestNames(\n n,\n index.map((i) => i.name),\n 3\n )\n ),\n });\n }\n\n const licenseKey =\n args.licenseKey?.trim() ||\n process.env.PLY_LICENSE_KEY?.trim() ||\n process.env.BASE_UI_LICENSE_KEY?.trim() ||\n '';\n\n if (pro.length && !licenseKey) {\n return failJson(\n `Pro components need PLY_LICENSE_KEY (or licenseKey): ${pro.join(', ')}.`,\n {\n pro,\n pricingUrl: `${SITE_URL}/pricing`,\n note: 'Set PLY_LICENSE_KEY on the MCP server process (BASE_UI_LICENSE_KEY still works), then retry. Free components can still be added with this tool.',\n freeCandidates: free,\n }\n );\n }\n\n // Also reject if free items pull Pro registryDependencies (closure).\n const queue = [...free];\n const seen = new Set<string>();\n const proDeps: string[] = [];\n while (queue.length) {\n const name = queue.shift()!;\n if (seen.has(name)) continue;\n seen.add(name);\n const entry = byName.get(name);\n if (!entry) continue;\n if (entry.tier === 'pro') {\n proDeps.push(name);\n continue;\n }\n queue.push(...entry.registryDependencies);\n }\n if (proDeps.length && !licenseKey) {\n return failJson(\n `Install blocked: free selection depends on Pro components: ${proDeps.join(', ')}.`,\n {\n proDependencies: proDeps,\n pricingUrl: `${SITE_URL}/pricing`,\n }\n );\n }\n\n const toInstall = [...free, ...pro];\n const replace = await resolveReplace(\n Boolean(args.overwrite),\n hooks.confirmReplace,\n `Replace existing files for ${toInstall.join(', ')}? This overwrites the copies already in the project.`,\n );\n const cliArgs = ['add', ...toInstall, '--yes'];\n if (replace.apply) cliArgs.push('--overwrite');\n\n const result = await runCli(cliArgs, {\n cwd,\n env: licenseKey\n ? { PLY_LICENSE_KEY: licenseKey, BASE_UI_LICENSE_KEY: licenseKey }\n : undefined,\n });\n const stdout = result.stdout.trim();\n const install = parseAddReport(stdout);\n const note = [\n `Files were written by ${CLI_BIN} (canonical installer). MCP does not replace the CLI.`,\n replace.confirmation === 'declined'\n ? 'Overwrite was not confirmed. Existing files were left in place.'\n : '',\n ]\n .filter(Boolean)\n .join(' ');\n if (!result.ok) {\n return failJson(`${CLI_BIN} add failed.`, {\n cwd,\n names: toInstall,\n exitCode: result.code,\n stdout,\n stderr: result.stderr.trim(),\n missingPackages: install.missingPackages,\n ...(install.installCommand ? { installCommand: install.installCommand } : {}),\n ...(replace.confirmation ? { confirmation: replace.confirmation } : {}),\n hint: `Ensure the project was initialized (${CLI_NPX} init --yes). CLI remains the canonical install path.`,\n });\n }\n\n return okJson({\n ok: true,\n cwd,\n installed: toInstall,\n cli: `${CLI_BIN} add --yes`,\n stdout,\n stderr: result.stderr.trim() || undefined,\n missingPackages: install.missingPackages,\n ...(install.installCommand ? { installCommand: install.installCommand } : {}),\n ...(replace.confirmation ? { confirmation: replace.confirmation } : {}),\n note,\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { spawn } from 'child_process';\nimport { CLI_PACKAGE } from './brand';\n\n/**\n * Resolve the ply-ui-cli entrypoint.\n * Order: PLY_CLI_PATH → local monorepo dist → node_modules bin → npx.\n */\nexport function resolveCliEntrypoint(): { command: string; argsPrefix: string[] } {\n const envPath = process.env.PLY_CLI_PATH?.trim() || process.env.BASE_UI_CLI_PATH?.trim();\n if (envPath && fs.existsSync(envPath)) {\n return { command: process.execPath, argsPrefix: [envPath] };\n }\n\n const sibling = path.resolve(__dirname, '../../cli/dist/index.js');\n if (fs.existsSync(sibling)) {\n return { command: process.execPath, argsPrefix: [sibling] };\n }\n\n for (const pkg of [CLI_PACKAGE, 'base-ui-cli']) {\n try {\n const pkgJson = require.resolve(`${pkg}/package.json`);\n const bin = path.join(path.dirname(pkgJson), 'dist', 'index.js');\n if (fs.existsSync(bin)) {\n return { command: process.execPath, argsPrefix: [bin] };\n }\n } catch {\n // not installed as a dependency\n }\n }\n\n // npx.cmd is named directly so the child process never needs a shell — see\n // the spawn call below, which deliberately does not set `shell`.\n return { command: process.platform === 'win32' ? 'npx.cmd' : 'npx', argsPrefix: ['-y', CLI_PACKAGE] };\n}\n\nexport interface RunCliResult {\n ok: boolean;\n code: number | null;\n stdout: string;\n stderr: string;\n}\n\nexport function runCli(\n cliArgs: string[],\n options: { cwd: string; env?: NodeJS.ProcessEnv; timeoutMs?: number } = { cwd: process.cwd() }\n): Promise<RunCliResult> {\n const { command, argsPrefix } = resolveCliEntrypoint();\n const args = [...argsPrefix, ...cliArgs];\n const timeoutMs = options.timeoutMs ?? 120_000;\n\n return new Promise((resolve) => {\n const child = spawn(command, args, {\n cwd: options.cwd,\n env: { ...process.env, ...options.env, FORCE_COLOR: '0' },\n });\n\n let stdout = '';\n let stderr = '';\n let settled = false;\n\n const timer = setTimeout(() => {\n if (settled) return;\n settled = true;\n child.kill('SIGTERM');\n resolve({\n ok: false,\n code: null,\n stdout,\n stderr: stderr + `\\nTimed out after ${timeoutMs}ms`,\n });\n }, timeoutMs);\n\n child.stdout.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf8');\n });\n child.stderr.on('data', (chunk: Buffer) => {\n stderr += chunk.toString('utf8');\n });\n child.on('error', (err) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve({ ok: false, code: null, stdout, stderr: err.message });\n });\n child.on('close', (code) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve({ ok: code === 0, code, stdout, stderr });\n });\n });\n}\n\n/** Project root for mutating tools (init/add). Prefer explicit cwd, else process cwd. */\nexport function resolveProjectCwd(cwd?: string): string {\n const root = cwd?.trim() || process.env.PLY_CWD?.trim() || process.env.BASE_UI_CWD?.trim() || process.cwd();\n return path.resolve(root);\n}\n","import { z } from 'zod';\n\nexport interface DoctorCheck {\n name: string;\n status: 'ok' | 'warn' | 'error';\n message: string;\n}\n\nexport interface AddInstallReport {\n missingPackages: string[];\n installCommand?: string;\n}\n\nexport interface UpdateFileResult {\n path: string;\n action: 'updated' | 'added' | 'reverted' | 'kept' | 'merged' | 'merge-conflict' | 'saved-aside';\n detail?: string;\n}\n\nconst STATUS: Record<string, DoctorCheck['status']> = {\n '✔': 'ok',\n '⚠': 'warn',\n '✖': 'error',\n};\n\nconst FILE_ACTION: Record<string, UpdateFileResult['action']> = {\n '↑': 'updated',\n '+': 'added',\n '↓': 'reverted',\n '=': 'kept',\n '⋈': 'merged',\n '⚠': 'merge-conflict',\n '⇄': 'saved-aside',\n};\n\nexport const doctorOutput = z.looseObject({\n ok: z.boolean(),\n checks: z.array(\n z.looseObject({\n name: z.string(),\n status: z.enum(['ok', 'warn', 'error']),\n message: z.string(),\n }),\n ),\n});\n\nexport const addOutput = z.looseObject({\n ok: z.boolean(),\n missingPackages: z.array(z.string()),\n installCommand: z.string().optional(),\n});\n\nexport const updateOutput = z.looseObject({\n ok: z.boolean(),\n files: z.array(\n z.looseObject({\n path: z.string(),\n action: z.enum(['updated', 'added', 'reverted', 'kept', 'merged', 'merge-conflict', 'saved-aside']),\n detail: z.string().optional(),\n }),\n ),\n});\n\nfunction plain(text: string): string {\n return text.replace(/\\u001b\\[[0-9;]*m/g, '').replace(/\\r\\n/g, '\\n');\n}\n\n/** Doctor prints `✔|⚠|✖ Name: message` on stdout. The summary line is ignored. */\nexport function parseDoctorChecks(stdout: string): DoctorCheck[] {\n const checks: DoctorCheck[] = [];\n for (const line of plain(stdout).split('\\n')) {\n const match = line.match(/^([✔⚠✖])\\s+([^:]+):\\s*(.*)$/);\n if (!match) continue;\n const status = STATUS[match[1]];\n if (!status) continue;\n checks.push({ name: match[2].trim(), status, message: match[3].trim() });\n }\n return checks;\n}\n\n/** Add prints the package-manager command instead of running it. */\nexport function parseAddReport(stdout: string): AddInstallReport {\n const match = plain(stdout).match(/Install missing npm dependenc(?:y|ies):\\n\\s+(.+)/);\n if (!match) return { missingPackages: [] };\n const installCommand = match[1].trim();\n const packages = installCommand.match(/^(?:npm install|pnpm add|yarn add|bun add)\\s+(.+)$/);\n return {\n installCommand,\n missingPackages: packages ? packages[1].split(/\\s+/).filter(Boolean) : [],\n };\n}\n\n/** Update prints one indented symbol line per file it touched or skipped. */\nexport function parseUpdateFiles(stdout: string): UpdateFileResult[] {\n const files: UpdateFileResult[] = [];\n for (const line of plain(stdout).split('\\n')) {\n const match = line.match(/^\\s*([↑+↓=⋈⚠⇄])\\s+(\\S+)(?:\\s+\\((.*)\\))?\\s*$/);\n if (!match) continue;\n const action = FILE_ACTION[match[1]];\n if (!action) continue;\n const detail = match[3]?.trim();\n files.push(detail ? { path: match[2], action, detail } : { path: match[2], action });\n }\n return files;\n}\n","import { z } from 'zod';\nimport { resolveProjectCwd, runCli } from '../cli';\nimport { isSafeItemName } from '../registry';\nimport { failJson, okJson } from '../result';\nimport { CLI_BIN } from '../brand';\n\nexport const diffComponentsInput = {\n names: z\n .array(z.string().min(1))\n .optional()\n .describe(\n 'Tracked component names to diff. Omit or pass [] to check every component in ply-ui-lock.json.'\n ),\n cwd: z\n .string()\n .optional()\n .describe(\n 'Project root containing ply-ui.json (defaults to MCP process cwd / PLY_CWD)'\n ),\n};\n\nexport async function diffComponents(args: { names?: string[]; cwd?: string } = {}) {\n try {\n const cwd = resolveProjectCwd(args.cwd);\n const names = (args.names ?? []).map((n) => n.trim()).filter(Boolean);\n for (const name of names) {\n if (!isSafeItemName(name)) {\n return failJson(`Invalid component name: '${name}'.`);\n }\n }\n\n const cliArgs = names.length ? ['diff', ...names] : ['diff'];\n const result = await runCli(cliArgs, { cwd });\n if (!result.ok) {\n return failJson(`${CLI_BIN} diff failed.`, {\n cwd,\n names,\n exitCode: result.code,\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim(),\n hint: 'Project must be initialized and components tracked in ply-ui-lock.json.',\n });\n }\n\n return okJson({\n ok: true,\n cwd,\n names: names.length ? names : 'all-tracked',\n cli: names.length ? `${CLI_BIN} diff ${names.join(' ')}` : `${CLI_BIN} diff`,\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim() || undefined,\n note: 'Read-only. Use update_components to apply upstream changes.',\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","import { z } from 'zod';\nimport { resolveProjectCwd, runCli } from '../cli';\nimport { parseDoctorChecks, doctorOutput } from '../cli-report';\nimport { failJson, okJson } from '../result';\nimport { CLI_BIN } from '../brand';\n\nexport { doctorOutput };\n\nexport const doctorInput = {\n cwd: z\n .string()\n .optional()\n .describe(\n 'Project root containing ply-ui.json (defaults to MCP process cwd / PLY_CWD). Read-only.'\n ),\n};\n\nexport async function doctor(args: { cwd?: string } = {}) {\n try {\n const cwd = resolveProjectCwd(args.cwd);\n const result = await runCli(['doctor'], { cwd });\n const stdout = result.stdout.trim();\n const body = {\n cwd,\n cli: `${CLI_BIN} doctor`,\n exitCode: result.code,\n stdout,\n stderr: result.stderr.trim() || undefined,\n checks: parseDoctorChecks(stdout),\n };\n if (!result.ok) {\n return failJson(`${CLI_BIN} doctor reported problems.`, body);\n }\n return okJson({ ok: true, ...body });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","import { z } from 'zod';\nimport { resolveProjectCwd, runCli } from '../cli';\nimport { failJson, okJson } from '../result';\nimport { CLI_BIN, CLI_NPX } from '../brand';\n\nexport const initProjectInput = {\n cwd: z\n .string()\n .optional()\n .describe(\n 'Project root to initialize (defaults to MCP process cwd / PLY_CWD). Always non-interactive (`init --yes`).'\n ),\n refreshEditorKit: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'Replace an editor kit that is already there (Cursor rule, snippets, and the design skill in .cursor/skills and .agents/skills). Maps to `init --refresh-editor-kit`.'\n ),\n};\n\nexport async function initProject(args: { cwd?: string; refreshEditorKit?: boolean } = {}) {\n try {\n const cwd = resolveProjectCwd(args.cwd);\n const cliArgs = ['init', '--yes'];\n if (args.refreshEditorKit) cliArgs.push('--refresh-editor-kit');\n const result = await runCli(cliArgs, { cwd });\n if (!result.ok) {\n return failJson(`${CLI_BIN} init failed.`, {\n cwd,\n exitCode: result.code,\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim(),\n hint: `CLI remains the canonical installer: ${CLI_NPX} init --yes`,\n });\n }\n return okJson({\n ok: true,\n cwd,\n cli: [CLI_BIN, ...cliArgs].join(' '),\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim() || undefined,\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","import { z } from 'zod';\nimport { resolveProjectCwd, runCli } from '../cli';\nimport { isSafeItemName } from '../registry';\nimport { parseUpdateFiles, updateOutput } from '../cli-report';\nimport { resolveReplace, type ReplaceDecision } from '../elicit';\nimport { failJson, okJson } from '../result';\nimport { CLI_BIN } from '../brand';\n\nexport { updateOutput };\n\nexport interface UpdateComponentsHooks {\n confirmReplace?: (message: string) => Promise<ReplaceDecision>;\n}\n\nexport const updateComponentsInput = {\n names: z\n .array(z.string().min(1))\n .optional()\n .describe(\n 'Tracked component names to update. Omit or pass [] to update every component in ply-ui-lock.json.'\n ),\n cwd: z\n .string()\n .optional()\n .describe(\n 'Project root containing ply-ui.json (defaults to MCP process cwd / PLY_CWD)'\n ),\n force: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'On conflict (both local and upstream changed), take the upstream version. Does not revert local-only edits.'\n ),\n overwriteLocal: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'Also revert files you edited that upstream did not change (`--overwrite-local`). Default skips those files.'\n ),\n merge: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'On conflict, apply a 3-way merge using the installed snapshot (`--merge`). force still wins.'\n ),\n};\n\n/**\n * Always non-interactive (`update --yes`). Conflicts are skipped unless `force`.\n * Local-only edits are skipped unless `overwriteLocal`.\n */\nexport async function updateComponents(\n args: {\n names?: string[];\n cwd?: string;\n force?: boolean;\n overwriteLocal?: boolean;\n merge?: boolean;\n } = {},\n hooks: UpdateComponentsHooks = {},\n) {\n try {\n const cwd = resolveProjectCwd(args.cwd);\n const names = (args.names ?? []).map((n) => n.trim()).filter(Boolean);\n for (const name of names) {\n if (!isSafeItemName(name)) {\n return failJson(`Invalid component name: '${name}'.`);\n }\n }\n\n const target = names.length ? names.join(', ') : 'tracked components';\n const replace = await resolveReplace(\n Boolean(args.force || args.overwriteLocal),\n hooks.confirmReplace,\n `Replace local files while updating ${target}? This overwrites copies already in the project.`,\n );\n const cliArgs = ['update', ...names, '--yes'];\n if (args.force && replace.apply) cliArgs.push('--force');\n if (args.overwriteLocal && replace.apply) cliArgs.push('--overwrite-local');\n if (args.merge) cliArgs.push('--merge');\n\n const result = await runCli(cliArgs, { cwd });\n const stdout = result.stdout.trim();\n const files = parseUpdateFiles(stdout);\n const note = [\n `Files were written by ${CLI_BIN} (canonical updater). MCP does not replace the CLI.`,\n replace.confirmation === 'declined'\n ? 'Replace was not confirmed. Conflicts and local-only edits were left in place.'\n : '',\n ]\n .filter(Boolean)\n .join(' ');\n if (!result.ok) {\n return failJson(`${CLI_BIN} update failed.`, {\n cwd,\n names,\n exitCode: result.code,\n stdout,\n stderr: result.stderr.trim(),\n files,\n ...(replace.confirmation ? { confirmation: replace.confirmation } : {}),\n hint: 'Run diff_components first. Conflicts need --force; local-only edits need overwriteLocal.',\n });\n }\n\n return okJson({\n ok: true,\n cwd,\n names: names.length ? names : 'all-tracked',\n force: Boolean(args.force && replace.apply),\n overwriteLocal: Boolean(args.overwriteLocal && replace.apply),\n merge: Boolean(args.merge),\n cli: [CLI_BIN, ...cliArgs].join(' '),\n stdout,\n stderr: result.stderr.trim() || undefined,\n files,\n ...(replace.confirmation ? { confirmation: replace.confirmation } : {}),\n note,\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { createCatalogMcpServer } from './catalog';\nimport { confirmReplace } from './elicit';\nimport { addComponents, addComponentsInput, addOutput } from './tools/add-components';\nimport { diffComponents, diffComponentsInput } from './tools/diff-components';\nimport { doctor, doctorInput, doctorOutput } from './tools/doctor';\nimport { initProject, initProjectInput } from './tools/init-project';\nimport { updateComponents, updateComponentsInput, updateOutput } from './tools/update-components';\nimport { CLI_BIN } from './brand';\n\nexport { PACKAGE_VERSION } from './version';\n\nexport interface CreateMcpServerOptions {\n /** When false, mutating CLI tools are omitted (hosted catalog MCP). */\n mutating?: boolean;\n}\n\nexport function createMcpServer(options: CreateMcpServerOptions = {}): McpServer {\n const mutating = options.mutating !== false;\n const server = createCatalogMcpServer();\n\n const readOnlyAnnotations = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n } as const;\n const writeAnnotations = {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: false,\n } as const;\n\n if (mutating) {\n server.registerTool(\n 'add_components',\n {\n title: 'Add Ply components',\n description:\n `Install registry components by shelling to \\`${CLI_BIN} add --yes\\`. --yes leaves an existing component in place; pass overwrite to replace it. Hosts that can ask confirm that overwrite first. Pro names require PLY_LICENSE_KEY (or licenseKey). Project must already have ply-ui.json. structuredContent includes missingPackages and installCommand.`,\n inputSchema: addComponentsInput,\n outputSchema: addOutput,\n annotations: writeAnnotations,\n },\n async (args) =>\n addComponents(args, {\n confirmReplace: (message) => confirmReplace(server, message),\n })\n );\n\n server.registerTool(\n 'init_project',\n {\n title: 'Initialize Ply in a project',\n description:\n `Run \\`${CLI_BIN} init --yes\\` in the target directory. Writes ply-ui.json, ply-ui.css, and icon sprites only when those files are missing, discovers the stylesheet already listed in angular.json, and inserts @source when it is absent. Writes the design skill to .cursor/skills and .agents/skills when those files are missing. Pass refreshEditorKit to replace an existing editor kit. Always non-interactive.`,\n inputSchema: initProjectInput,\n annotations: writeAnnotations,\n },\n async (args) => initProject(args)\n );\n\n server.registerTool(\n 'doctor',\n {\n title: 'Verify Ply project setup',\n description:\n `Run \\`${CLI_BIN} doctor\\` (read-only). structuredContent.checks lists each ✔/⚠/✖ line. Returns isError when the CLI exits non-zero.`,\n inputSchema: doctorInput,\n outputSchema: doctorOutput,\n annotations: readOnlyAnnotations,\n },\n async (args) => doctor(args)\n );\n\n server.registerTool(\n 'diff_components',\n {\n title: 'Diff installed Ply components',\n description:\n `Run \\`${CLI_BIN} diff\\` against tracked components. Read-only. Omit names to check everything in ply-ui-lock.json.`,\n inputSchema: diffComponentsInput,\n annotations: readOnlyAnnotations,\n },\n async (args) => diffComponents(args)\n );\n\n server.registerTool(\n 'update_components',\n {\n title: 'Update installed Ply components',\n description:\n `Run \\`${CLI_BIN} update --yes\\`. Untouched files take upstream. Conflicts stay local and the CLI exits non-zero unless force or merge. Local-only edits skip unless overwriteLocal. Hosts that can ask confirm force and overwriteLocal before those flags replace files. structuredContent.files is one result per file line.`,\n inputSchema: updateComponentsInput,\n outputSchema: updateOutput,\n annotations: writeAnnotations,\n },\n async (args) =>\n updateComponents(args, {\n confirmReplace: (message) => confirmReplace(server, message),\n })\n );\n }\n\n return server;\n}\n","import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport { createMcpServer, PACKAGE_VERSION } from './server';\nimport { MCP_PACKAGE } from './brand';\nimport { mcpProtectedResource, wwwAuthenticate } from './auth-metadata';\n\nexport interface HttpOptions {\n host: string;\n port: number;\n readOnly: boolean;\n authToken?: string;\n}\n\nfunction setCors(res: ServerResponse): void {\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');\n res.setHeader(\n 'Access-Control-Allow-Headers',\n 'Content-Type, Authorization, Mcp-Session-Id, MCP-Protocol-Version'\n );\n}\n\nfunction unauthorized(res: ServerResponse, resourceMetadataUrl: string): void {\n setCors(res);\n res.writeHead(401, {\n 'Content-Type': 'application/json',\n 'WWW-Authenticate': wwwAuthenticate(resourceMetadataUrl),\n });\n res.end(JSON.stringify({ error: 'Unauthorized' }));\n}\n\nfunction checkAuth(req: IncomingMessage, token?: string): boolean {\n if (!token) return true;\n const header = req.headers.authorization;\n return header === `Bearer ${token}`;\n}\n\nasync function readBody(req: IncomingMessage): Promise<unknown> {\n const chunks: Buffer[] = [];\n for await (const chunk of req) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n const raw = Buffer.concat(chunks).toString('utf8').trim();\n if (!raw) return undefined;\n return JSON.parse(raw);\n}\n\n/**\n * Streamable HTTP MCP. ChatGPT / Gemini chat apps need a public HTTPS URL\n * pointing at `/mcp`. Mutating tools only work when this process can see\n * the consumer project (local `--http`, not a remote catalog host).\n */\nexport function startHttpServer(options: HttpOptions): ReturnType<typeof createServer> {\n const server = createServer(async (req, res) => {\n try {\n const url = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`);\n\n if (req.method === 'OPTIONS') {\n setCors(res);\n res.writeHead(204);\n res.end();\n return;\n }\n\n if (url.pathname === '/' && req.method === 'GET') {\n setCors(res);\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n ok: true,\n name: MCP_PACKAGE,\n version: PACKAGE_VERSION,\n transport: 'streamable-http',\n mcp: '/mcp',\n mutating: !options.readOnly,\n })\n );\n return;\n }\n\n if (url.pathname === '/.well-known/oauth-protected-resource' && req.method === 'GET') {\n setCors(res);\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end(\n JSON.stringify(\n mcpProtectedResource(new URL('/mcp', url.origin).href, Boolean(options.authToken))\n )\n );\n return;\n }\n\n if (url.pathname !== '/mcp') {\n setCors(res);\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Not found. MCP is POST/GET /mcp.' }));\n return;\n }\n\n if (!checkAuth(req, options.authToken)) {\n unauthorized(res, new URL('/.well-known/oauth-protected-resource', url.origin).href);\n return;\n }\n\n setCors(res);\n const mcp = createMcpServer({ mutating: !options.readOnly });\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n });\n await mcp.connect(transport);\n const parsedBody = req.method === 'POST' ? await readBody(req) : undefined;\n await transport.handleRequest(req, res, parsedBody);\n } catch (err) {\n console.error(`${MCP_PACKAGE} HTTP error:`, err);\n if (!res.headersSent) {\n res.writeHead(500, { 'Content-Type': 'application/json' });\n }\n if (!res.writableEnded) {\n res.end(JSON.stringify({ error: err instanceof Error ? err.message : String(err) }));\n }\n }\n });\n\n server.listen(options.port, options.host, () => {\n const addr = server.address();\n const port = typeof addr === 'object' && addr ? addr.port : options.port;\n console.error(\n `${MCP_PACKAGE} v${PACKAGE_VERSION} Streamable HTTP on http://${options.host}:${port}/mcp` +\n (options.readOnly ? ' (read-only catalog)' : '')\n );\n });\n return server;\n}\n","/** Canonical auth.md skill. Registration is not offered; see the file. */\nexport const AUTH_MD_URL = 'https://ply-ui.com/auth.md';\n\nexport interface ProtectedResourceMetadata {\n resource: string;\n resource_name: string;\n resource_documentation: string;\n resource_logo_uri: string;\n authorization_servers: string[];\n scopes_supported: string[];\n bearer_methods_supported: string[];\n}\n\n/** RFC 9728 metadata for one MCP origin. An empty authorization_servers list means registration is off. */\nexport function mcpProtectedResource(resource: string, bearer: boolean): ProtectedResourceMetadata {\n return {\n resource,\n resource_name: 'Ply MCP',\n resource_documentation: AUTH_MD_URL,\n resource_logo_uri: 'https://ply-ui.com/assets/pwa/apple-touch-icon.png',\n authorization_servers: [],\n scopes_supported: [],\n bearer_methods_supported: bearer ? ['header'] : [],\n };\n}\n\nexport function wwwAuthenticate(resourceMetadataUrl: string): string {\n return `Bearer resource_metadata=\"${resourceMetadataUrl}\"`;\n}\n"],"mappings":"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","names":["import_mcp","import_zod","import_zod","import_zod","CATEGORIES","import_zod","fs","path","import_zod","import_zod","import_zod","import_zod","import_zod"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ply-ui-mcp",
3
- "version": "0.1.30",
3
+ "version": "0.1.32",
4
4
  "description": "Ply MCP server — stdio or Streamable HTTP (--http). List, search, init, doctor, diff, update, and add Angular + Tailwind components (Pro with PLY_LICENSE_KEY). Not MUI Base UI.",
5
5
  "type": "commonjs",
6
6
  "main": "dist/index.js",
@@ -62,7 +62,7 @@
62
62
  "esbuild": "0.28.2",
63
63
  "fast-uri": "3.1.8",
64
64
  "proxy-addr": "2.0.8",
65
- "hono": "4.13.7",
65
+ "hono": "4.13.13",
66
66
  "qs": "6.16.0"
67
67
  }
68
68
  }