@frontmcp/uipack 0.6.3 → 0.7.2

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.
Files changed (56) hide show
  1. package/CLAUDE.md +0 -14
  2. package/adapters/index.js +50 -47
  3. package/adapters/platform-meta.d.ts.map +1 -1
  4. package/adapters/response-builder.d.ts +16 -3
  5. package/adapters/response-builder.d.ts.map +1 -1
  6. package/bridge-runtime/iife-generator.d.ts.map +1 -1
  7. package/bridge-runtime/index.js +4 -0
  8. package/build/index.d.ts +1 -1
  9. package/build/index.d.ts.map +1 -1
  10. package/build/index.js +61 -69
  11. package/bundler/index.js +35 -34
  12. package/dependency/import-map.d.ts.map +1 -1
  13. package/dependency/index.js +22 -29
  14. package/esm/adapters/index.mjs +52 -42
  15. package/esm/bridge-runtime/index.mjs +4 -0
  16. package/esm/build/index.mjs +30 -32
  17. package/esm/bundler/index.mjs +19 -11
  18. package/esm/dependency/index.mjs +18 -18
  19. package/esm/handlebars/index.mjs +9 -8
  20. package/esm/index.mjs +107 -126
  21. package/esm/package.json +3 -2
  22. package/esm/registry/index.mjs +53 -49
  23. package/esm/renderers/index.mjs +15 -21
  24. package/esm/runtime/index.mjs +16 -15
  25. package/esm/theme/index.mjs +8 -0
  26. package/esm/tool-template/index.mjs +23 -15
  27. package/esm/typings/index.mjs +4 -0
  28. package/esm/utils/index.mjs +9 -56
  29. package/esm/validation/index.mjs +9 -8
  30. package/handlebars/index.js +4 -10
  31. package/index.js +186 -211
  32. package/package.json +3 -2
  33. package/preview/generic-preview.d.ts +4 -5
  34. package/preview/generic-preview.d.ts.map +1 -1
  35. package/preview/types.d.ts +15 -1
  36. package/preview/types.d.ts.map +1 -1
  37. package/registry/index.js +61 -63
  38. package/registry/render-template.d.ts.map +1 -1
  39. package/renderers/index.js +16 -28
  40. package/renderers/utils/detect.d.ts.map +1 -1
  41. package/runtime/index.js +20 -25
  42. package/runtime/sanitizer.d.ts.map +1 -1
  43. package/theme/css-to-theme.d.ts +0 -27
  44. package/theme/css-to-theme.d.ts.map +1 -1
  45. package/theme/index.js +8 -0
  46. package/tool-template/index.js +30 -28
  47. package/typings/dts-parser.d.ts.map +1 -1
  48. package/typings/index.js +4 -0
  49. package/utils/index.d.ts +2 -3
  50. package/utils/index.d.ts.map +1 -1
  51. package/utils/index.js +7 -63
  52. package/validation/index.js +6 -12
  53. package/utils/escape-html.d.ts +0 -102
  54. package/utils/escape-html.d.ts.map +0 -1
  55. package/utils/safe-stringify.d.ts +0 -30
  56. package/utils/safe-stringify.d.ts.map +0 -1
package/index.js CHANGED
@@ -30,79 +30,12 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
30
  ));
31
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
32
 
33
- // libs/uipack/src/utils/safe-stringify.ts
34
- function safeStringify(value, space) {
35
- const seen = /* @__PURE__ */ new WeakSet();
36
- try {
37
- return JSON.stringify(
38
- value,
39
- (_key, val) => {
40
- if (typeof val === "object" && val !== null) {
41
- if (seen.has(val)) return "[Circular]";
42
- seen.add(val);
43
- }
44
- return val;
45
- },
46
- space
47
- );
48
- } catch {
49
- return JSON.stringify({ error: "Output could not be serialized" });
50
- }
51
- }
52
- var init_safe_stringify = __esm({
53
- "libs/uipack/src/utils/safe-stringify.ts"() {
54
- "use strict";
55
- }
56
- });
57
-
58
- // libs/uipack/src/utils/escape-html.ts
59
- function escapeHtml(str) {
60
- if (str === null || str === void 0) {
61
- return "";
62
- }
63
- const s = String(str);
64
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
65
- }
66
- function escapeHtmlAttr(str) {
67
- return str.replace(/&/g, "&amp;").replace(/"/g, "&quot;");
68
- }
69
- function escapeJsString(str) {
70
- return str.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
71
- }
72
- function escapeScriptClose(jsonString) {
73
- return jsonString.replace(/<\//g, "<\\/");
74
- }
75
- function safeJsonForScript(value) {
76
- if (value === void 0) {
77
- return "null";
78
- }
79
- try {
80
- const jsonString = JSON.stringify(value, (_key, val) => {
81
- if (typeof val === "bigint") {
82
- return val.toString();
83
- }
84
- return val;
85
- });
86
- if (jsonString === void 0) {
87
- return "null";
88
- }
89
- return escapeScriptClose(jsonString);
90
- } catch {
91
- return '{"error":"Value could not be serialized"}';
92
- }
93
- }
94
- var init_escape_html = __esm({
95
- "libs/uipack/src/utils/escape-html.ts"() {
96
- "use strict";
97
- }
98
- });
99
-
100
33
  // libs/uipack/src/utils/index.ts
34
+ var import_utils;
101
35
  var init_utils = __esm({
102
36
  "libs/uipack/src/utils/index.ts"() {
103
37
  "use strict";
104
- init_safe_stringify();
105
- init_escape_html();
38
+ import_utils = require("@frontmcp/utils");
106
39
  }
107
40
  });
108
41
 
@@ -820,6 +753,13 @@ var init_theme = __esm({
820
753
 
821
754
  // libs/uipack/src/theme/css-to-theme.ts
822
755
  function cssToTailwindTheme(userCss) {
756
+ if (userCss.length > MAX_CSS_INPUT_LENGTH) {
757
+ return {
758
+ themeBlock: "",
759
+ remainingCss: userCss,
760
+ colorVars: /* @__PURE__ */ new Map()
761
+ };
762
+ }
823
763
  const colorVars = /* @__PURE__ */ new Map();
824
764
  const regex = new RegExp(COLOR_VAR_REGEX.source, "g");
825
765
  let match;
@@ -852,11 +792,12 @@ function buildTailwindStyleBlock(userCss) {
852
792
  ${parts.join("\n\n")}
853
793
  </style>`;
854
794
  }
855
- var COLOR_VAR_REGEX;
795
+ var COLOR_VAR_REGEX, MAX_CSS_INPUT_LENGTH;
856
796
  var init_css_to_theme = __esm({
857
797
  "libs/uipack/src/theme/css-to-theme.ts"() {
858
798
  "use strict";
859
799
  COLOR_VAR_REGEX = /--(color-[\w-]+):\s*([^;]+);/g;
800
+ MAX_CSS_INPUT_LENGTH = 1e5;
860
801
  }
861
802
  });
862
803
 
@@ -901,6 +842,9 @@ function isTemplateBuilderFunction(fn) {
901
842
  return true;
902
843
  }
903
844
  function containsJsx(source) {
845
+ if (source.length > MAX_TEMPLATE_LENGTH) {
846
+ return false;
847
+ }
904
848
  if (/<[A-Z][a-zA-Z0-9]*(\s|>|\/)/.test(source)) {
905
849
  return true;
906
850
  }
@@ -925,6 +869,9 @@ function containsJsx(source) {
925
869
  return false;
926
870
  }
927
871
  function containsMdxSyntax(source) {
872
+ if (source.length > MAX_TEMPLATE_LENGTH) {
873
+ return false;
874
+ }
928
875
  if (/<[A-Z][a-zA-Z0-9]*/.test(source)) {
929
876
  return true;
930
877
  }
@@ -998,9 +945,11 @@ function detectTemplateType(template) {
998
945
  reason: "Unknown template type, defaulting to HTML"
999
946
  };
1000
947
  }
948
+ var MAX_TEMPLATE_LENGTH;
1001
949
  var init_detect = __esm({
1002
950
  "libs/uipack/src/renderers/utils/detect.ts"() {
1003
951
  "use strict";
952
+ MAX_TEMPLATE_LENGTH = 5e4;
1004
953
  }
1005
954
  });
1006
955
 
@@ -1221,7 +1170,7 @@ var init_helpers = __esm({
1221
1170
  idCounter = 0;
1222
1171
  builtinHelpers = {
1223
1172
  // Escaping
1224
- escapeHtml,
1173
+ escapeHtml: import_utils.escapeHtml,
1225
1174
  // Formatting
1226
1175
  formatDate,
1227
1176
  formatCurrency,
@@ -1392,7 +1341,7 @@ __export(handlebars_exports, {
1392
1341
  createHandlebarsRenderer: () => createHandlebarsRenderer,
1393
1342
  defaultValue: () => defaultValue,
1394
1343
  eq: () => eq,
1395
- escapeHtml: () => escapeHtml,
1344
+ escapeHtml: () => import_utils.escapeHtml,
1396
1345
  extractAll: () => extractAll,
1397
1346
  extractExpressions: () => extractExpressions,
1398
1347
  extractInputPaths: () => extractInputPaths,
@@ -2228,12 +2177,12 @@ var init_mdx_client_renderer = __esm({
2228
2177
  ...outputProps,
2229
2178
  ...props
2230
2179
  };
2231
- const escapedMdx = escapeScriptClose(JSON.stringify(template));
2232
- const escapedProps = escapeScriptClose(JSON.stringify(spreadProps));
2233
- const safeContainerId = escapeJsString(containerId);
2234
- const loadingHtml = showLoading ? `<div class="mdx-loading">${escapeHtml(loadingMessage)}</div>` : "";
2180
+ const escapedMdx = (0, import_utils.escapeScriptClose)(JSON.stringify(template));
2181
+ const escapedProps = (0, import_utils.escapeScriptClose)(JSON.stringify(spreadProps));
2182
+ const safeContainerId = (0, import_utils.escapeJsString)(containerId);
2183
+ const loadingHtml = showLoading ? `<div class="mdx-loading">${(0, import_utils.escapeHtml)(loadingMessage)}</div>` : "";
2235
2184
  return `
2236
- <div id="${escapeHtml(containerId)}">${loadingHtml}</div>
2185
+ <div id="${(0, import_utils.escapeHtml)(containerId)}">${loadingHtml}</div>
2237
2186
  <script type="module">
2238
2187
  (async function() {
2239
2188
  try {
@@ -2446,7 +2395,7 @@ function sha256Buffer(buffer) {
2446
2395
  }
2447
2396
  async function hashFile(filePath) {
2448
2397
  try {
2449
- const content = await (0, import_promises.readFile)(filePath);
2398
+ const content = await (0, import_utils8.readFileBuffer)(filePath);
2450
2399
  return sha256Buffer(content);
2451
2400
  } catch {
2452
2401
  return void 0;
@@ -2497,7 +2446,7 @@ async function collectLocalDependencies(filePath, baseDir, collected, maxDepth,
2497
2446
  if (!(0, import_fs.existsSync)(filePath)) return;
2498
2447
  collected.add(filePath);
2499
2448
  try {
2500
- const content = await (0, import_promises.readFile)(filePath, "utf8");
2449
+ const content = await (0, import_utils8.readFile)(filePath);
2501
2450
  const imports = extractImportPaths(content);
2502
2451
  for (const importPath of imports) {
2503
2452
  if (!importPath.startsWith(".") && !importPath.startsWith("/")) {
@@ -2566,14 +2515,14 @@ function generateBuildId() {
2566
2515
  const random = Math.random().toString(36).substring(2, 10);
2567
2516
  return `${timestamp}-${random}`;
2568
2517
  }
2569
- var import_crypto, import_promises, import_fs, import_path;
2518
+ var import_crypto, import_fs, import_path, import_utils8;
2570
2519
  var init_hash_calculator = __esm({
2571
2520
  "libs/uipack/src/bundler/file-cache/hash-calculator.ts"() {
2572
2521
  "use strict";
2573
2522
  import_crypto = require("crypto");
2574
- import_promises = require("fs/promises");
2575
2523
  import_fs = require("fs");
2576
2524
  import_path = require("path");
2525
+ import_utils8 = require("@frontmcp/utils");
2577
2526
  }
2578
2527
  });
2579
2528
 
@@ -3420,13 +3369,16 @@ function generateUMDShim(dependencies, options = {}) {
3420
3369
  console.warn('UMD shim failed:', e);
3421
3370
  }
3422
3371
  })();` : `window.__esm_shim = ${shimObject};`;
3423
- return minify ? code.replace(/\s+/g, " ").replace(/\s*([{},:])\s*/g, "$1") : code;
3372
+ if (minify && code.length <= 1e5) {
3373
+ return code.replace(/\s+/g, " ").replace(/\s*([{},:])\s*/g, "$1");
3374
+ }
3375
+ return code;
3424
3376
  }
3425
3377
  function generateCDNScriptTags(dependencies) {
3426
3378
  return dependencies.filter((dep) => !dep.esm).map((dep) => {
3427
- const attrs = [`src="${escapeHtmlAttr(dep.cdnUrl)}"`];
3379
+ const attrs = [`src="${(0, import_utils.escapeHtmlAttr)(dep.cdnUrl)}"`];
3428
3380
  if (dep.integrity) {
3429
- attrs.push(`integrity="${escapeHtmlAttr(dep.integrity)}"`);
3381
+ attrs.push(`integrity="${(0, import_utils.escapeHtmlAttr)(dep.integrity)}"`);
3430
3382
  }
3431
3383
  attrs.push('crossorigin="anonymous"');
3432
3384
  return `<script ${attrs.join(" ")}></script>`;
@@ -3434,9 +3386,9 @@ function generateCDNScriptTags(dependencies) {
3434
3386
  }
3435
3387
  function generateESMScriptTags(dependencies) {
3436
3388
  return dependencies.filter((dep) => dep.esm).map((dep) => {
3437
- const attrs = ['type="module"', `src="${escapeHtmlAttr(dep.cdnUrl)}"`];
3389
+ const attrs = ['type="module"', `src="${(0, import_utils.escapeHtmlAttr)(dep.cdnUrl)}"`];
3438
3390
  if (dep.integrity) {
3439
- attrs.push(`integrity="${escapeHtmlAttr(dep.integrity)}"`);
3391
+ attrs.push(`integrity="${(0, import_utils.escapeHtmlAttr)(dep.integrity)}"`);
3440
3392
  }
3441
3393
  attrs.push('crossorigin="anonymous"');
3442
3394
  return `<script ${attrs.join(" ")}></script>`;
@@ -3722,14 +3674,14 @@ __export(filesystem_exports, {
3722
3674
  function createFilesystemStorage(options) {
3723
3675
  return new FilesystemStorage(options);
3724
3676
  }
3725
- var import_promises2, import_path3, import_fs3, import_crypto3, CacheInitializationError, CacheOperationError, StorageNotInitializedError, DEFAULT_FS_OPTIONS, FilesystemStorage;
3677
+ var import_path3, import_fs3, import_crypto3, import_utils16, CacheInitializationError, CacheOperationError, StorageNotInitializedError, DEFAULT_FS_OPTIONS, FilesystemStorage;
3726
3678
  var init_filesystem = __esm({
3727
3679
  "libs/uipack/src/bundler/file-cache/storage/filesystem.ts"() {
3728
3680
  "use strict";
3729
- import_promises2 = require("fs/promises");
3730
3681
  import_path3 = require("path");
3731
3682
  import_fs3 = require("fs");
3732
3683
  import_crypto3 = require("crypto");
3684
+ import_utils16 = require("@frontmcp/utils");
3733
3685
  init_interface();
3734
3686
  CacheInitializationError = class extends Error {
3735
3687
  cause;
@@ -3781,7 +3733,7 @@ var init_filesystem = __esm({
3781
3733
  async initialize() {
3782
3734
  if (this.initialized) return;
3783
3735
  try {
3784
- await (0, import_promises2.mkdir)(this.options.cacheDir, { recursive: true });
3736
+ await (0, import_utils16.mkdir)(this.options.cacheDir, { recursive: true });
3785
3737
  await this.loadStats();
3786
3738
  this.initialized = true;
3787
3739
  } catch (error) {
@@ -3800,7 +3752,7 @@ var init_filesystem = __esm({
3800
3752
  this.updateHitRate();
3801
3753
  return void 0;
3802
3754
  }
3803
- const content = await (0, import_promises2.readFile)(filePath, "utf8");
3755
+ const content = await (0, import_utils16.readFile)(filePath, "utf8");
3804
3756
  const entry = JSON.parse(content);
3805
3757
  if (Date.now() > entry.metadata.expiresAt) {
3806
3758
  await this.delete(key);
@@ -3856,7 +3808,7 @@ var init_filesystem = __esm({
3856
3808
  const filePath = this.getFilePath(key);
3857
3809
  try {
3858
3810
  if (!(0, import_fs3.existsSync)(filePath)) return false;
3859
- const content = await (0, import_promises2.readFile)(filePath, "utf8");
3811
+ const content = await (0, import_utils16.readFile)(filePath, "utf8");
3860
3812
  const entry = JSON.parse(content);
3861
3813
  if (Date.now() > entry.metadata.expiresAt) {
3862
3814
  await this.delete(key);
@@ -3875,9 +3827,9 @@ var init_filesystem = __esm({
3875
3827
  const filePath = this.getFilePath(key);
3876
3828
  try {
3877
3829
  if (!(0, import_fs3.existsSync)(filePath)) return false;
3878
- const content = await (0, import_promises2.readFile)(filePath, "utf8");
3830
+ const content = await (0, import_utils16.readFile)(filePath, "utf8");
3879
3831
  const entry = JSON.parse(content);
3880
- await (0, import_promises2.unlink)(filePath);
3832
+ await (0, import_utils16.unlink)(filePath);
3881
3833
  this.stats.entries = Math.max(0, this.stats.entries - 1);
3882
3834
  this.stats.totalSize = Math.max(0, this.stats.totalSize - entry.metadata.size);
3883
3835
  return true;
@@ -3891,8 +3843,8 @@ var init_filesystem = __esm({
3891
3843
  async clear() {
3892
3844
  this.ensureInitialized();
3893
3845
  try {
3894
- await (0, import_promises2.rm)(this.options.cacheDir, { recursive: true, force: true });
3895
- await (0, import_promises2.mkdir)(this.options.cacheDir, { recursive: true });
3846
+ await (0, import_utils16.rm)(this.options.cacheDir, { recursive: true, force: true });
3847
+ await (0, import_utils16.mkdir)(this.options.cacheDir, { recursive: true });
3896
3848
  this.stats = {
3897
3849
  entries: 0,
3898
3850
  totalSize: 0,
@@ -3917,21 +3869,21 @@ var init_filesystem = __esm({
3917
3869
  this.ensureInitialized();
3918
3870
  let removed = 0;
3919
3871
  try {
3920
- const files = await (0, import_promises2.readdir)(this.options.cacheDir);
3872
+ const files = await (0, import_utils16.readdir)(this.options.cacheDir);
3921
3873
  for (const file of files) {
3922
3874
  if (!file.endsWith(this.options.extension)) continue;
3923
3875
  const filePath = (0, import_path3.join)(this.options.cacheDir, file);
3924
3876
  try {
3925
- const content = await (0, import_promises2.readFile)(filePath, "utf8");
3877
+ const content = await (0, import_utils16.readFile)(filePath, "utf8");
3926
3878
  const entry = JSON.parse(content);
3927
3879
  if (Date.now() > entry.metadata.expiresAt) {
3928
- await (0, import_promises2.unlink)(filePath);
3880
+ await (0, import_utils16.unlink)(filePath);
3929
3881
  this.stats.entries = Math.max(0, this.stats.entries - 1);
3930
3882
  this.stats.totalSize = Math.max(0, this.stats.totalSize - entry.metadata.size);
3931
3883
  removed++;
3932
3884
  }
3933
3885
  } catch {
3934
- await (0, import_promises2.unlink)(filePath).catch(() => {
3886
+ await (0, import_utils16.unlink)(filePath).catch(() => {
3935
3887
  });
3936
3888
  removed++;
3937
3889
  }
@@ -3957,8 +3909,8 @@ var init_filesystem = __esm({
3957
3909
  * Write a cache entry to disk.
3958
3910
  */
3959
3911
  async writeEntry(filePath, entry) {
3960
- await (0, import_promises2.mkdir)((0, import_path3.dirname)(filePath), { recursive: true });
3961
- await (0, import_promises2.writeFile)(filePath, JSON.stringify(entry, null, 2), "utf8");
3912
+ await (0, import_utils16.mkdir)((0, import_path3.dirname)(filePath), { recursive: true });
3913
+ await (0, import_utils16.writeFile)(filePath, JSON.stringify(entry, null, 2));
3962
3914
  }
3963
3915
  /**
3964
3916
  * Ensure the storage is initialized.
@@ -3974,14 +3926,14 @@ var init_filesystem = __esm({
3974
3926
  */
3975
3927
  async loadStats() {
3976
3928
  try {
3977
- const files = await (0, import_promises2.readdir)(this.options.cacheDir);
3929
+ const files = await (0, import_utils16.readdir)(this.options.cacheDir);
3978
3930
  let entries = 0;
3979
3931
  let totalSize = 0;
3980
3932
  for (const file of files) {
3981
3933
  if (!file.endsWith(this.options.extension)) continue;
3982
3934
  const filePath = (0, import_path3.join)(this.options.cacheDir, file);
3983
3935
  try {
3984
- const content = await (0, import_promises2.readFile)(filePath, "utf8");
3936
+ const content = await (0, import_utils16.readFile)(filePath, "utf8");
3985
3937
  const entry = JSON.parse(content);
3986
3938
  entries++;
3987
3939
  totalSize += entry.metadata.size;
@@ -4010,7 +3962,7 @@ var init_filesystem = __esm({
4010
3962
  */
4011
3963
  async evictLRU() {
4012
3964
  try {
4013
- const files = await (0, import_promises2.readdir)(this.options.cacheDir);
3965
+ const files = await (0, import_utils16.readdir)(this.options.cacheDir);
4014
3966
  let oldestKey = null;
4015
3967
  let oldestTime = Infinity;
4016
3968
  let corruptedFile = null;
@@ -4018,7 +3970,7 @@ var init_filesystem = __esm({
4018
3970
  if (!file.endsWith(this.options.extension)) continue;
4019
3971
  const filePath = (0, import_path3.join)(this.options.cacheDir, file);
4020
3972
  try {
4021
- const content = await (0, import_promises2.readFile)(filePath, "utf8");
3973
+ const content = await (0, import_utils16.readFile)(filePath, "utf8");
4022
3974
  const entry = JSON.parse(content);
4023
3975
  if (entry.metadata.lastAccessedAt < oldestTime) {
4024
3976
  oldestTime = entry.metadata.lastAccessedAt;
@@ -4030,7 +3982,7 @@ var init_filesystem = __esm({
4030
3982
  }
4031
3983
  if (corruptedFile) {
4032
3984
  try {
4033
- await (0, import_promises2.unlink)(corruptedFile);
3985
+ await (0, import_utils16.unlink)(corruptedFile);
4034
3986
  this.stats.entries = Math.max(0, this.stats.entries - 1);
4035
3987
  return true;
4036
3988
  } catch {
@@ -4330,14 +4282,14 @@ async function createRedisBuilder(redisClient, keyPrefix = "frontmcp:ui:build:")
4330
4282
  await storage.initialize();
4331
4283
  return new ComponentBuilder(storage);
4332
4284
  }
4333
- var import_promises3, import_fs4, import_path4, import_crypto4, ComponentBuilder;
4285
+ var import_fs4, import_path4, import_crypto4, import_utils17, ComponentBuilder;
4334
4286
  var init_component_builder = __esm({
4335
4287
  "libs/uipack/src/bundler/file-cache/component-builder.ts"() {
4336
4288
  "use strict";
4337
- import_promises3 = require("fs/promises");
4338
4289
  import_fs4 = require("fs");
4339
4290
  import_path4 = require("path");
4340
4291
  import_crypto4 = require("crypto");
4292
+ import_utils17 = require("@frontmcp/utils");
4341
4293
  init_hash_calculator();
4342
4294
  init_resolver();
4343
4295
  init_import_map();
@@ -4384,7 +4336,7 @@ var init_component_builder = __esm({
4384
4336
  };
4385
4337
  }
4386
4338
  }
4387
- const source = await (0, import_promises3.readFile)(absoluteEntryPath, "utf8");
4339
+ const source = await (0, import_utils17.readFile)(absoluteEntryPath, "utf8");
4388
4340
  const resolver = new DependencyResolver({ platform });
4389
4341
  const resolvedDeps = [];
4390
4342
  for (const pkg of externals) {
@@ -4707,10 +4659,10 @@ __export(index_exports, {
4707
4659
  detectTemplateMode: () => detectTemplateMode,
4708
4660
  detectTemplateType: () => detectTemplateType,
4709
4661
  errorDisplay: () => errorDisplay,
4710
- escapeHtml: () => escapeHtml,
4711
- escapeHtmlAttr: () => escapeHtmlAttr,
4712
- escapeJsString: () => escapeJsString,
4713
- escapeScriptClose: () => escapeScriptClose,
4662
+ escapeHtml: () => import_utils.escapeHtml,
4663
+ escapeHtmlAttr: () => import_utils.escapeHtmlAttr,
4664
+ escapeJsString: () => import_utils.escapeJsString,
4665
+ escapeScriptClose: () => import_utils.escapeScriptClose,
4714
4666
  executeTemplate: () => executeTemplate,
4715
4667
  executeTranspiledCode: () => executeTranspiledCode,
4716
4668
  extractExternalPackages: () => extractExternalPackages,
@@ -4814,8 +4766,8 @@ __export(index_exports, {
4814
4766
  rendererRegistry: () => rendererRegistry,
4815
4767
  resolveDependencies: () => resolveDependencies,
4816
4768
  resolveServingMode: () => resolveServingMode,
4817
- safeJsonForScript: () => safeJsonForScript,
4818
- safeStringify: () => safeStringify,
4769
+ safeJsonForScript: () => import_utils.safeJsonForScript,
4770
+ safeStringify: () => import_utils.safeStringify,
4819
4771
  sanitizeCSPDomains: () => sanitizeCSPDomains,
4820
4772
  sanitizeInput: () => sanitizeInput,
4821
4773
  sha256: () => sha256,
@@ -4930,16 +4882,13 @@ function buildUIMeta(options) {
4930
4882
  case "generic-mcp":
4931
4883
  case "gemini":
4932
4884
  default:
4933
- meta["frontmcp/html"] = html;
4934
- meta["frontmcp/mimeType"] = "text/html+mcp";
4935
- if (rendererType) meta["frontmcp/type"] = rendererType;
4936
- if (contentHash) meta["frontmcp/contentHash"] = contentHash;
4937
- if (manifestUri) meta["frontmcp/manifestUri"] = manifestUri;
4938
- if (token) meta["frontmcp/widgetToken"] = token;
4939
- if (directUrl) meta["frontmcp/directUrl"] = directUrl;
4940
4885
  meta["ui/html"] = html;
4941
4886
  meta["ui/mimeType"] = "text/html+mcp";
4942
4887
  if (rendererType) meta["ui/type"] = rendererType;
4888
+ if (contentHash) meta["ui/contentHash"] = contentHash;
4889
+ if (manifestUri) meta["ui/manifestUri"] = manifestUri;
4890
+ if (token) meta["ui/widgetToken"] = token;
4891
+ if (directUrl) meta["ui/directUrl"] = directUrl;
4943
4892
  if (platformType === "claude") {
4944
4893
  return buildClaudeMeta(meta, uiConfig);
4945
4894
  } else if (platformType === "gemini") {
@@ -4998,34 +4947,37 @@ function buildIDEMeta(meta, uiConfig) {
4998
4947
  }
4999
4948
  return meta;
5000
4949
  }
5001
- function buildFrontMCPCSP(csp) {
5002
- const result = {};
5003
- if (csp.connectDomains?.length) {
5004
- result.connectDomains = csp.connectDomains;
5005
- }
5006
- if (csp.resourceDomains?.length) {
5007
- result.resourceDomains = csp.resourceDomains;
5008
- }
5009
- return result;
5010
- }
5011
4950
  function buildGenericMeta(meta, uiConfig) {
5012
- if (uiConfig.widgetAccessible) {
5013
- meta["frontmcp/widgetAccessible"] = true;
5014
- }
5015
4951
  if (uiConfig.csp) {
5016
- meta["frontmcp/widgetCSP"] = buildFrontMCPCSP(uiConfig.csp);
4952
+ const csp = {};
4953
+ if (uiConfig.csp.connectDomains?.length) {
4954
+ csp.connectDomains = uiConfig.csp.connectDomains;
4955
+ }
4956
+ if (uiConfig.csp.resourceDomains?.length) {
4957
+ csp.resourceDomains = uiConfig.csp.resourceDomains;
4958
+ }
4959
+ if (Object.keys(csp).length > 0) {
4960
+ meta["ui/csp"] = csp;
4961
+ }
5017
4962
  }
5018
4963
  if (uiConfig.displayMode) {
5019
- meta["frontmcp/displayMode"] = uiConfig.displayMode;
5020
- }
5021
- if (uiConfig.widgetDescription) {
5022
- meta["frontmcp/widgetDescription"] = uiConfig.widgetDescription;
4964
+ const displayModeMap = {
4965
+ inline: "inline",
4966
+ fullscreen: "fullscreen",
4967
+ pip: "pip",
4968
+ widget: "inline",
4969
+ panel: "fullscreen"
4970
+ };
4971
+ const mappedMode = displayModeMap[uiConfig.displayMode];
4972
+ if (mappedMode) {
4973
+ meta["ui/displayMode"] = mappedMode;
4974
+ }
5023
4975
  }
5024
4976
  if (uiConfig.prefersBorder !== void 0) {
5025
- meta["frontmcp/prefersBorder"] = uiConfig.prefersBorder;
4977
+ meta["ui/prefersBorder"] = uiConfig.prefersBorder;
5026
4978
  }
5027
4979
  if (uiConfig.sandboxDomain) {
5028
- meta["frontmcp/domain"] = uiConfig.sandboxDomain;
4980
+ meta["ui/domain"] = uiConfig.sandboxDomain;
5029
4981
  }
5030
4982
  return meta;
5031
4983
  }
@@ -5261,7 +5213,7 @@ function buildToolResponseContent(options) {
5261
5213
  const { rawOutput, htmlContent, servingMode, useStructuredContent, platformType } = options;
5262
5214
  if (servingMode === "static") {
5263
5215
  return {
5264
- content: [{ type: "text", text: safeStringify(rawOutput) }],
5216
+ content: [{ type: "text", text: (0, import_utils.safeStringify)(rawOutput) }],
5265
5217
  structuredContent: useStructuredContent ? rawOutput : void 0,
5266
5218
  contentCleared: false,
5267
5219
  format: "json-only"
@@ -5269,7 +5221,7 @@ function buildToolResponseContent(options) {
5269
5221
  }
5270
5222
  if (servingMode === "hybrid") {
5271
5223
  return {
5272
- content: [{ type: "text", text: safeStringify(rawOutput) }],
5224
+ content: [{ type: "text", text: (0, import_utils.safeStringify)(rawOutput) }],
5273
5225
  structuredContent: useStructuredContent ? rawOutput : void 0,
5274
5226
  contentCleared: false,
5275
5227
  format: "json-only"
@@ -5277,15 +5229,25 @@ function buildToolResponseContent(options) {
5277
5229
  }
5278
5230
  if (useStructuredContent) {
5279
5231
  if (htmlContent) {
5280
- return {
5281
- content: [{ type: "text", text: htmlContent }],
5282
- structuredContent: rawOutput,
5283
- contentCleared: false,
5284
- format: "structured-content"
5285
- };
5232
+ const htmlInContent = platformType === "openai" || platformType === "ext-apps";
5233
+ if (htmlInContent) {
5234
+ return {
5235
+ content: [{ type: "text", text: htmlContent }],
5236
+ structuredContent: rawOutput,
5237
+ contentCleared: false,
5238
+ format: "structured-content"
5239
+ };
5240
+ } else {
5241
+ return {
5242
+ content: [{ type: "text", text: (0, import_utils.safeStringify)(rawOutput) }],
5243
+ structuredContent: rawOutput,
5244
+ contentCleared: false,
5245
+ format: "structured-content"
5246
+ };
5247
+ }
5286
5248
  }
5287
5249
  return {
5288
- content: [{ type: "text", text: safeStringify(rawOutput) }],
5250
+ content: [{ type: "text", text: (0, import_utils.safeStringify)(rawOutput) }],
5289
5251
  structuredContent: rawOutput,
5290
5252
  contentCleared: false,
5291
5253
  format: "json-only"
@@ -5306,7 +5268,7 @@ function buildToolResponseContent(options) {
5306
5268
  type: "text",
5307
5269
  text: `## Data
5308
5270
  \`\`\`json
5309
- ${safeStringify(
5271
+ ${(0, import_utils.safeStringify)(
5310
5272
  rawOutput,
5311
5273
  2
5312
5274
  )}
@@ -5323,7 +5285,7 @@ ${htmlContent}
5323
5285
  };
5324
5286
  }
5325
5287
  return {
5326
- content: [{ type: "text", text: safeStringify(rawOutput, 2) }],
5288
+ content: [{ type: "text", text: (0, import_utils.safeStringify)(rawOutput, 2) }],
5327
5289
  contentCleared: false,
5328
5290
  format: "json-only"
5329
5291
  };
@@ -6154,7 +6116,11 @@ FrontMcpBridge.prototype._setupDataToolCallHandler = function() {
6154
6116
  };
6155
6117
  `.trim();
6156
6118
  }
6119
+ var MAX_MINIFY_CODE_LENGTH = 5e5;
6157
6120
  function minifyJS(code) {
6121
+ if (code.length > MAX_MINIFY_CODE_LENGTH) {
6122
+ return code;
6123
+ }
6158
6124
  return code.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "").replace(/\s+/g, " ").replace(/\s*([{};,:()[\]])\s*/g, "$1").replace(/;\}/g, "}").trim();
6159
6125
  }
6160
6126
  function generatePlatformBundle(platform, options = {}) {
@@ -6794,7 +6760,11 @@ function detectPIIType(value) {
6794
6760
  if (isIPv4(value)) return "IP";
6795
6761
  return null;
6796
6762
  }
6763
+ var MAX_PII_TEXT_LENGTH = 1e5;
6797
6764
  function redactPIIFromText(text) {
6765
+ if (text.length > MAX_PII_TEXT_LENGTH) {
6766
+ return text;
6767
+ }
6798
6768
  let result = text;
6799
6769
  result = result.replace(PII_PATTERNS.creditCardInText, REDACTION_TOKENS.CARD);
6800
6770
  result = result.replace(PII_PATTERNS.ssnInText, REDACTION_TOKENS.ID);
@@ -6913,7 +6883,7 @@ function createTemplateHelpers() {
6913
6883
  /**
6914
6884
  * Escape HTML special characters to prevent XSS
6915
6885
  */
6916
- escapeHtml,
6886
+ escapeHtml: import_utils.escapeHtml,
6917
6887
  /**
6918
6888
  * Format a date for display
6919
6889
  */
@@ -7017,7 +6987,7 @@ function wrapToolUI(options) {
7017
6987
  widgetAccessible,
7018
6988
  hostContext
7019
6989
  });
7020
- const pageTitle = title || `${escapeHtml(toolName)} - Tool Result`;
6990
+ const pageTitle = title || `${(0, import_utils.escapeHtml)(toolName)} - Tool Result`;
7021
6991
  return `<!DOCTYPE html>
7022
6992
  <html lang="en">
7023
6993
  <head>
@@ -7170,7 +7140,7 @@ function wrapToolUIUniversal(options) {
7170
7140
  resourceMode
7171
7141
  });
7172
7142
  const bridgeScript = includeBridge ? BRIDGE_SCRIPT_TAGS.universal : "";
7173
- const pageTitle = title || `${escapeHtml(toolName)} - Tool Result`;
7143
+ const pageTitle = title || `${(0, import_utils.escapeHtml)(toolName)} - Tool Result`;
7174
7144
  return `<!DOCTYPE html>
7175
7145
  <html lang="en">
7176
7146
  <head>
@@ -7284,7 +7254,7 @@ function wrapToolUIMinimal(options) {
7284
7254
  window.__mcpWidgetAccessible = ${helpers.jsonEmbed(widgetAccessible)};
7285
7255
  window.__mcpHostContext = ${helpers.jsonEmbed(contextData)};
7286
7256
  </script>`;
7287
- const pageTitle = title || `${escapeHtml(toolName)} - Tool Result`;
7257
+ const pageTitle = title || `${(0, import_utils.escapeHtml)(toolName)} - Tool Result`;
7288
7258
  return `<!DOCTYPE html>
7289
7259
  <html lang="en">
7290
7260
  <head>
@@ -7434,7 +7404,7 @@ function wrapLeanWidgetShell(options) {
7434
7404
  <head>
7435
7405
  <meta charset="UTF-8">
7436
7406
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7437
- <title>${escapeHtml(title || toolName)}</title>
7407
+ <title>${(0, import_utils.escapeHtml)(title || toolName)}</title>
7438
7408
  ${fontPreconnect}
7439
7409
  ${fontStylesheets}
7440
7410
  ${tailwindScript}
@@ -7835,7 +7805,7 @@ function wrapHybridWidgetShell(options) {
7835
7805
  <head>
7836
7806
  <meta charset="UTF-8">
7837
7807
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7838
- <title>${escapeHtml(title || toolName)}</title>
7808
+ <title>${(0, import_utils.escapeHtml)(title || toolName)}</title>
7839
7809
  ${fontPreconnect}
7840
7810
  ${fontStylesheets}
7841
7811
  ${tailwindScript}
@@ -8377,7 +8347,7 @@ function wrapStaticWidgetUniversal(options) {
8377
8347
  }, 100);
8378
8348
  }
8379
8349
  </script>` : "";
8380
- const pageTitle = title || `${escapeHtml(toolName)} - Tool Widget`;
8350
+ const pageTitle = title || `${(0, import_utils.escapeHtml)(toolName)} - Tool Widget`;
8381
8351
  const loaderHtml = isReactBased && componentCode && !hasEmbeddedData ? `
8382
8352
  <!-- Loading State -->
8383
8353
  <div id="frontmcp-loader" style="display: flex; align-items: center; justify-content: center; padding: 2rem; gap: 0.5rem;">
@@ -8559,13 +8529,13 @@ function validationErrorBox(options) {
8559
8529
  class="validation-error flex items-start gap-3 p-4 bg-red-50 border border-red-200 text-red-800 rounded-lg"
8560
8530
  role="alert"
8561
8531
  data-testid="validation-error"
8562
- data-component="${escapeHtml(componentName)}"
8563
- data-param="${escapeHtml(invalidParam)}"
8532
+ data-component="${(0, import_utils.escapeHtml)(componentName)}"
8533
+ data-param="${(0, import_utils.escapeHtml)(invalidParam)}"
8564
8534
  >
8565
8535
  ${errorIcon}
8566
8536
  <div class="min-w-0">
8567
- <p class="font-semibold text-sm">${escapeHtml(componentName)}: Invalid Configuration</p>
8568
- <p class="text-sm opacity-90 mt-0.5">The "${escapeHtml(invalidParam)}" parameter is invalid.</p>
8537
+ <p class="font-semibold text-sm">${(0, import_utils.escapeHtml)(componentName)}: Invalid Configuration</p>
8538
+ <p class="text-sm opacity-90 mt-0.5">The "${(0, import_utils.escapeHtml)(invalidParam)}" parameter is invalid.</p>
8569
8539
  </div>
8570
8540
  </div>`;
8571
8541
  }
@@ -8779,7 +8749,7 @@ function describeZodType(schema) {
8779
8749
  }
8780
8750
 
8781
8751
  // libs/uipack/src/validation/template-validator.ts
8782
- init_expression_extractor();
8752
+ init_handlebars();
8783
8753
  function validateTemplate(template, outputSchema, options = {}) {
8784
8754
  const { inputSchema, warnOnOptional = true, suggestSimilar = true, maxSuggestionDistance = 3 } = options;
8785
8755
  const errors = [];
@@ -9145,7 +9115,7 @@ function safeInputToRecord(input) {
9145
9115
  return {};
9146
9116
  }
9147
9117
  var defaultHelpers = {
9148
- escapeHtml,
9118
+ escapeHtml: import_utils.escapeHtml,
9149
9119
  formatDate: (date, format) => {
9150
9120
  const d = date instanceof Date ? date : new Date(date);
9151
9121
  if (format === "iso") return d.toISOString();
@@ -10002,7 +9972,7 @@ var BaseBuilder = class {
10002
9972
  "<head>",
10003
9973
  '<meta charset="UTF-8">',
10004
9974
  '<meta name="viewport" content="width=device-width, initial-scale=1.0">',
10005
- `<title>${escapeHtml(title)}</title>`
9975
+ `<title>${(0, import_utils.escapeHtml)(title)}</title>`
10006
9976
  ];
10007
9977
  parts.push(buildFontPreconnect());
10008
9978
  parts.push(buildFontStylesheets({ inter: true }));
@@ -10119,7 +10089,7 @@ ${body}
10119
10089
  input,
10120
10090
  output,
10121
10091
  helpers: {
10122
- escapeHtml,
10092
+ escapeHtml: import_utils.escapeHtml,
10123
10093
  formatDate: (date, format) => {
10124
10094
  const d = typeof date === "string" ? new Date(date) : date;
10125
10095
  if (isNaN(d.getTime())) return String(date);
@@ -11213,11 +11183,11 @@ var OpenAIPreview = class {
11213
11183
  const theme = mockData?.theme || "light";
11214
11184
  const displayMode = mockData?.displayMode || "inline";
11215
11185
  const toolResponses = mockData?.toolResponses || {};
11216
- const safeTheme = safeJsonForScript(theme);
11217
- const safeDisplayMode = safeJsonForScript(displayMode);
11218
- const safeToolResponses = safeJsonForScript(toolResponses);
11219
- const safeInput = safeJsonForScript(input);
11220
- const safeOutput = safeJsonForScript(output);
11186
+ const safeTheme = (0, import_utils.safeJsonForScript)(theme);
11187
+ const safeDisplayMode = (0, import_utils.safeJsonForScript)(displayMode);
11188
+ const safeToolResponses = (0, import_utils.safeJsonForScript)(toolResponses);
11189
+ const safeInput = (0, import_utils.safeJsonForScript)(input);
11190
+ const safeOutput = (0, import_utils.safeJsonForScript)(output);
11221
11191
  const mockScript = `
11222
11192
  <script>
11223
11193
  // Mock window.openai for builder mode
@@ -11258,8 +11228,8 @@ var OpenAIPreview = class {
11258
11228
  */
11259
11229
  combineHybridForBuilder(result, input, output, mockData) {
11260
11230
  let html = result.vendorShell;
11261
- const safeInput = safeJsonForScript(input);
11262
- const safeOutput = safeJsonForScript(output);
11231
+ const safeInput = (0, import_utils.safeJsonForScript)(input);
11232
+ const safeOutput = (0, import_utils.safeJsonForScript)(output);
11263
11233
  html = html.replace(DATA_PLACEHOLDERS.input, `window.__mcpToolInput = ${safeInput};`).replace(DATA_PLACEHOLDERS.output, `window.__mcpToolOutput = ${safeOutput};`).replace(DATA_PLACEHOLDERS.structuredContent, `window.__mcpStructuredContent = ${safeOutput};`);
11264
11234
  const componentScript = `
11265
11235
  <script type="module">
@@ -11334,8 +11304,8 @@ var ClaudePreview = class {
11334
11304
  }
11335
11305
  forExecutionHybrid(result, input, output) {
11336
11306
  let html = result.vendorShell;
11337
- const safeInput = safeJsonForScript(input);
11338
- const safeOutput = safeJsonForScript(output);
11307
+ const safeInput = (0, import_utils.safeJsonForScript)(input);
11308
+ const safeOutput = (0, import_utils.safeJsonForScript)(output);
11339
11309
  html = html.replace(DATA_PLACEHOLDERS2.input, `window.__mcpToolInput = ${safeInput};`).replace(DATA_PLACEHOLDERS2.output, `window.__mcpToolOutput = ${safeOutput};`).replace(DATA_PLACEHOLDERS2.structuredContent, `window.__mcpStructuredContent = ${safeOutput};`);
11340
11310
  const componentScript = `
11341
11311
  <script type="module">
@@ -11396,9 +11366,9 @@ var ClaudePreview = class {
11396
11366
  * to prevent XSS attacks from malicious data.
11397
11367
  */
11398
11368
  buildClaudeInlineHtml(input, output) {
11399
- const safeInput = safeJsonForScript(input);
11400
- const safeOutput = safeJsonForScript(output);
11401
- const escapedOutputDisplay = escapeHtml(JSON.stringify(output, null, 2));
11369
+ const safeInput = (0, import_utils.safeJsonForScript)(input);
11370
+ const safeOutput = (0, import_utils.safeJsonForScript)(output);
11371
+ const escapedOutputDisplay = (0, import_utils.escapeHtml)(JSON.stringify(output, null, 2));
11402
11372
  return `<!DOCTYPE html>
11403
11373
  <html lang="en">
11404
11374
  <head>
@@ -11475,13 +11445,12 @@ var GenericPreview = class {
11475
11445
  forDiscoveryStatic(result, toolName, _description) {
11476
11446
  const resourceUri = `resource://widget/${toolName}`;
11477
11447
  const _meta = {
11478
- // Primary namespace
11479
- "frontmcp/outputTemplate": resourceUri,
11480
- "frontmcp/widgetCSP": {
11481
- connect_domains: ["esm.sh", "cdn.tailwindcss.com"],
11482
- resource_domains: ["esm.sh", "cdn.tailwindcss.com", "fonts.googleapis.com", "fonts.gstatic.com"]
11448
+ // Use ui/* namespace for generic MCP clients
11449
+ "ui/resourceUri": resourceUri,
11450
+ "ui/widgetCSP": {
11451
+ connectDomains: ["esm.sh", "cdn.tailwindcss.com"],
11452
+ resourceDomains: ["esm.sh", "cdn.tailwindcss.com", "fonts.googleapis.com", "fonts.gstatic.com"]
11483
11453
  },
11484
- // Fallback for compatibility
11485
11454
  "ui/mimeType": "text/html+mcp"
11486
11455
  };
11487
11456
  return {
@@ -11492,10 +11461,11 @@ var GenericPreview = class {
11492
11461
  }
11493
11462
  forDiscoveryHybrid(result, _toolName, _description) {
11494
11463
  const _meta = {
11495
- "frontmcp/outputTemplate": result.shellResourceUri,
11496
- "frontmcp/widgetCSP": {
11497
- connect_domains: ["esm.sh", "cdn.tailwindcss.com"],
11498
- resource_domains: ["esm.sh", "cdn.tailwindcss.com", "fonts.googleapis.com", "fonts.gstatic.com"]
11464
+ // Use ui/* namespace for generic MCP clients
11465
+ "ui/resourceUri": result.shellResourceUri,
11466
+ "ui/widgetCSP": {
11467
+ connectDomains: ["esm.sh", "cdn.tailwindcss.com"],
11468
+ resourceDomains: ["esm.sh", "cdn.tailwindcss.com", "fonts.googleapis.com", "fonts.gstatic.com"]
11499
11469
  },
11500
11470
  "ui/mimeType": "text/html+mcp"
11501
11471
  };
@@ -11507,7 +11477,7 @@ var GenericPreview = class {
11507
11477
  }
11508
11478
  forDiscoveryInline(result, _toolName, _description) {
11509
11479
  const _meta = {
11510
- "frontmcp/html": result.loaderShell,
11480
+ // Use ui/* namespace for generic MCP clients
11511
11481
  "ui/html": result.loaderShell,
11512
11482
  "ui/mimeType": "text/html+mcp"
11513
11483
  };
@@ -11523,7 +11493,6 @@ var GenericPreview = class {
11523
11493
  const html = this.injectBuilderMode(result.html, input, output, mockData);
11524
11494
  return {
11525
11495
  _meta: {
11526
- "frontmcp/html": html,
11527
11496
  "ui/html": html
11528
11497
  },
11529
11498
  html,
@@ -11539,13 +11508,12 @@ var GenericPreview = class {
11539
11508
  }
11540
11509
  forExecutionHybrid(result, input, output, builderMode, mockData) {
11541
11510
  const _meta = {
11542
- "frontmcp/component": result.componentChunk
11511
+ "ui/component": result.componentChunk
11543
11512
  };
11544
11513
  if (builderMode) {
11545
11514
  const html = this.combineHybridForBuilder(result, input, output, mockData);
11546
11515
  return {
11547
11516
  _meta: {
11548
- "frontmcp/html": html,
11549
11517
  "ui/html": html
11550
11518
  },
11551
11519
  html,
@@ -11561,7 +11529,6 @@ var GenericPreview = class {
11561
11529
  }
11562
11530
  forExecutionInline(result, input, output, _builderMode, _mockData) {
11563
11531
  const _meta = {
11564
- "frontmcp/html": "<!-- Full widget will be generated -->",
11565
11532
  "ui/html": "<!-- Full widget will be generated -->"
11566
11533
  };
11567
11534
  return {
@@ -11583,11 +11550,11 @@ var GenericPreview = class {
11583
11550
  const theme = mockData?.theme || "light";
11584
11551
  const displayMode = mockData?.displayMode || "inline";
11585
11552
  const toolResponses = mockData?.toolResponses || {};
11586
- const safeTheme = safeJsonForScript(theme);
11587
- const safeDisplayMode = safeJsonForScript(displayMode);
11588
- const safeToolResponses = safeJsonForScript(toolResponses);
11589
- const safeInput = safeJsonForScript(input);
11590
- const safeOutput = safeJsonForScript(output);
11553
+ const safeTheme = (0, import_utils.safeJsonForScript)(theme);
11554
+ const safeDisplayMode = (0, import_utils.safeJsonForScript)(displayMode);
11555
+ const safeToolResponses = (0, import_utils.safeJsonForScript)(toolResponses);
11556
+ const safeInput = (0, import_utils.safeJsonForScript)(input);
11557
+ const safeOutput = (0, import_utils.safeJsonForScript)(output);
11591
11558
  const mockScript = `
11592
11559
  <script>
11593
11560
  // Mock FrontMCP bridge for builder mode
@@ -11620,8 +11587,8 @@ var GenericPreview = class {
11620
11587
  */
11621
11588
  combineHybridForBuilder(result, input, output, mockData) {
11622
11589
  let html = result.vendorShell;
11623
- const safeInput = safeJsonForScript(input);
11624
- const safeOutput = safeJsonForScript(output);
11590
+ const safeInput = (0, import_utils.safeJsonForScript)(input);
11591
+ const safeOutput = (0, import_utils.safeJsonForScript)(output);
11625
11592
  html = html.replace(DATA_PLACEHOLDERS3.input, `window.__mcpToolInput = ${safeInput};`).replace(DATA_PLACEHOLDERS3.output, `window.__mcpToolOutput = ${safeOutput};`).replace(DATA_PLACEHOLDERS3.structuredContent, `window.__mcpStructuredContent = ${safeOutput};`);
11626
11593
  const componentScript = `
11627
11594
  <script type="module">
@@ -11727,16 +11694,16 @@ function heading(text, level = 2) {
11727
11694
  3: "text-lg font-medium text-text-primary mb-2",
11728
11695
  4: "text-base font-medium text-text-secondary mb-2"
11729
11696
  }[level] || "";
11730
- return `<${tag} class="${classes}">${escapeHtml(text)}</${tag}>`;
11697
+ return `<${tag} class="${classes}">${(0, import_utils.escapeHtml)(text)}</${tag}>`;
11731
11698
  }
11732
11699
  function paragraph(text, className = "") {
11733
- return `<p class="text-text-secondary ${className}">${escapeHtml(text)}</p>`;
11700
+ return `<p class="text-text-secondary ${className}">${(0, import_utils.escapeHtml)(text)}</p>`;
11734
11701
  }
11735
11702
  function keyValue(key, value, className = "") {
11736
11703
  const displayValue = typeof value === "boolean" ? value ? "Yes" : "No" : String(value);
11737
11704
  return `<div class="flex justify-between items-center py-2 border-b border-border ${className}">
11738
- <span class="text-text-secondary">${escapeHtml(key)}</span>
11739
- <span class="text-text-primary font-medium">${escapeHtml(displayValue)}</span>
11705
+ <span class="text-text-secondary">${(0, import_utils.escapeHtml)(key)}</span>
11706
+ <span class="text-text-primary font-medium">${(0, import_utils.escapeHtml)(displayValue)}</span>
11740
11707
  </div>`;
11741
11708
  }
11742
11709
  function dataList(items) {
@@ -11749,9 +11716,9 @@ function errorDisplay(message, details) {
11749
11716
  <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
11750
11717
  <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/>
11751
11718
  </svg>
11752
- <span class="font-medium">${escapeHtml(message)}</span>
11719
+ <span class="font-medium">${(0, import_utils.escapeHtml)(message)}</span>
11753
11720
  </div>
11754
- ${details ? `<p class="mt-2 text-sm text-text-secondary">${escapeHtml(details)}</p>` : ""}
11721
+ ${details ? `<p class="mt-2 text-sm text-text-secondary">${(0, import_utils.escapeHtml)(details)}</p>` : ""}
11755
11722
  </div>`;
11756
11723
  }
11757
11724
  function successDisplay(message, details) {
@@ -11760,9 +11727,9 @@ function successDisplay(message, details) {
11760
11727
  <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
11761
11728
  <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
11762
11729
  </svg>
11763
- <span class="font-medium">${escapeHtml(message)}</span>
11730
+ <span class="font-medium">${(0, import_utils.escapeHtml)(message)}</span>
11764
11731
  </div>
11765
- ${details ? `<p class="mt-2 text-sm text-text-secondary">${escapeHtml(details)}</p>` : ""}
11732
+ ${details ? `<p class="mt-2 text-sm text-text-secondary">${(0, import_utils.escapeHtml)(details)}</p>` : ""}
11766
11733
  </div>`;
11767
11734
  }
11768
11735
  function loadingDisplay(message = "Loading...") {
@@ -11772,7 +11739,7 @@ function loadingDisplay(message = "Loading...") {
11772
11739
  <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
11773
11740
  <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
11774
11741
  </svg>
11775
- <span>${escapeHtml(message)}</span>
11742
+ <span>${(0, import_utils.escapeHtml)(message)}</span>
11776
11743
  </div>
11777
11744
  </div>`;
11778
11745
  }
@@ -12746,7 +12713,11 @@ init_renderers();
12746
12713
  var import_crypto2 = require("crypto");
12747
12714
 
12748
12715
  // libs/uipack/src/registry/render-template.ts
12716
+ var MAX_MDX_SOURCE_LENGTH = 1e5;
12749
12717
  function containsMdxSyntax2(source) {
12718
+ if (source.length > MAX_MDX_SOURCE_LENGTH) {
12719
+ return false;
12720
+ }
12750
12721
  if (/<[A-Z][a-zA-Z0-9]*/.test(source)) {
12751
12722
  return true;
12752
12723
  }
@@ -13589,7 +13560,11 @@ function getSubpathFromSpecifier(specifier) {
13589
13560
  }
13590
13561
  return void 0;
13591
13562
  }
13563
+ var MAX_IMPORT_STATEMENT_LENGTH = 2e3;
13592
13564
  function parseImportStatement(statement) {
13565
+ if (statement.length > MAX_IMPORT_STATEMENT_LENGTH) {
13566
+ return null;
13567
+ }
13593
13568
  const namedMatch = /import\s+(?:\{[^}]*\}|\*\s+as\s+\w+|\w+)\s+from\s+['"]([^'"]+)['"]/.exec(statement);
13594
13569
  if (namedMatch) {
13595
13570
  return namedMatch[1];