@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.
- package/CLAUDE.md +0 -14
- package/adapters/index.js +50 -47
- package/adapters/platform-meta.d.ts.map +1 -1
- package/adapters/response-builder.d.ts +16 -3
- package/adapters/response-builder.d.ts.map +1 -1
- package/bridge-runtime/iife-generator.d.ts.map +1 -1
- package/bridge-runtime/index.js +4 -0
- package/build/index.d.ts +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +61 -69
- package/bundler/index.js +35 -34
- package/dependency/import-map.d.ts.map +1 -1
- package/dependency/index.js +22 -29
- package/esm/adapters/index.mjs +52 -42
- package/esm/bridge-runtime/index.mjs +4 -0
- package/esm/build/index.mjs +30 -32
- package/esm/bundler/index.mjs +19 -11
- package/esm/dependency/index.mjs +18 -18
- package/esm/handlebars/index.mjs +9 -8
- package/esm/index.mjs +107 -126
- package/esm/package.json +3 -2
- package/esm/registry/index.mjs +53 -49
- package/esm/renderers/index.mjs +15 -21
- package/esm/runtime/index.mjs +16 -15
- package/esm/theme/index.mjs +8 -0
- package/esm/tool-template/index.mjs +23 -15
- package/esm/typings/index.mjs +4 -0
- package/esm/utils/index.mjs +9 -56
- package/esm/validation/index.mjs +9 -8
- package/handlebars/index.js +4 -10
- package/index.js +186 -211
- package/package.json +3 -2
- package/preview/generic-preview.d.ts +4 -5
- package/preview/generic-preview.d.ts.map +1 -1
- package/preview/types.d.ts +15 -1
- package/preview/types.d.ts.map +1 -1
- package/registry/index.js +61 -63
- package/registry/render-template.d.ts.map +1 -1
- package/renderers/index.js +16 -28
- package/renderers/utils/detect.d.ts.map +1 -1
- package/runtime/index.js +20 -25
- package/runtime/sanitizer.d.ts.map +1 -1
- package/theme/css-to-theme.d.ts +0 -27
- package/theme/css-to-theme.d.ts.map +1 -1
- package/theme/index.js +8 -0
- package/tool-template/index.js +30 -28
- package/typings/dts-parser.d.ts.map +1 -1
- package/typings/index.js +4 -0
- package/utils/index.d.ts +2 -3
- package/utils/index.d.ts.map +1 -1
- package/utils/index.js +7 -63
- package/validation/index.js +6 -12
- package/utils/escape-html.d.ts +0 -102
- package/utils/escape-html.d.ts.map +0 -1
- package/utils/safe-stringify.d.ts +0 -30
- package/utils/safe-stringify.d.ts.map +0 -1
package/esm/index.mjs
CHANGED
|
@@ -8,79 +8,18 @@ var __export = (target, all) => {
|
|
|
8
8
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
// libs/uipack/src/utils/safe-stringify.ts
|
|
12
|
-
function safeStringify(value, space) {
|
|
13
|
-
const seen = /* @__PURE__ */ new WeakSet();
|
|
14
|
-
try {
|
|
15
|
-
return JSON.stringify(
|
|
16
|
-
value,
|
|
17
|
-
(_key, val) => {
|
|
18
|
-
if (typeof val === "object" && val !== null) {
|
|
19
|
-
if (seen.has(val)) return "[Circular]";
|
|
20
|
-
seen.add(val);
|
|
21
|
-
}
|
|
22
|
-
return val;
|
|
23
|
-
},
|
|
24
|
-
space
|
|
25
|
-
);
|
|
26
|
-
} catch {
|
|
27
|
-
return JSON.stringify({ error: "Output could not be serialized" });
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
var init_safe_stringify = __esm({
|
|
31
|
-
"libs/uipack/src/utils/safe-stringify.ts"() {
|
|
32
|
-
"use strict";
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
// libs/uipack/src/utils/escape-html.ts
|
|
37
|
-
function escapeHtml(str) {
|
|
38
|
-
if (str === null || str === void 0) {
|
|
39
|
-
return "";
|
|
40
|
-
}
|
|
41
|
-
const s = String(str);
|
|
42
|
-
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
43
|
-
}
|
|
44
|
-
function escapeHtmlAttr(str) {
|
|
45
|
-
return str.replace(/&/g, "&").replace(/"/g, """);
|
|
46
|
-
}
|
|
47
|
-
function escapeJsString(str) {
|
|
48
|
-
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");
|
|
49
|
-
}
|
|
50
|
-
function escapeScriptClose(jsonString) {
|
|
51
|
-
return jsonString.replace(/<\//g, "<\\/");
|
|
52
|
-
}
|
|
53
|
-
function safeJsonForScript(value) {
|
|
54
|
-
if (value === void 0) {
|
|
55
|
-
return "null";
|
|
56
|
-
}
|
|
57
|
-
try {
|
|
58
|
-
const jsonString = JSON.stringify(value, (_key, val) => {
|
|
59
|
-
if (typeof val === "bigint") {
|
|
60
|
-
return val.toString();
|
|
61
|
-
}
|
|
62
|
-
return val;
|
|
63
|
-
});
|
|
64
|
-
if (jsonString === void 0) {
|
|
65
|
-
return "null";
|
|
66
|
-
}
|
|
67
|
-
return escapeScriptClose(jsonString);
|
|
68
|
-
} catch {
|
|
69
|
-
return '{"error":"Value could not be serialized"}';
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
var init_escape_html = __esm({
|
|
73
|
-
"libs/uipack/src/utils/escape-html.ts"() {
|
|
74
|
-
"use strict";
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
|
|
78
11
|
// libs/uipack/src/utils/index.ts
|
|
12
|
+
import {
|
|
13
|
+
safeStringify,
|
|
14
|
+
escapeHtml,
|
|
15
|
+
escapeHtmlAttr,
|
|
16
|
+
escapeJsString,
|
|
17
|
+
escapeScriptClose,
|
|
18
|
+
safeJsonForScript
|
|
19
|
+
} from "@frontmcp/utils";
|
|
79
20
|
var init_utils = __esm({
|
|
80
21
|
"libs/uipack/src/utils/index.ts"() {
|
|
81
22
|
"use strict";
|
|
82
|
-
init_safe_stringify();
|
|
83
|
-
init_escape_html();
|
|
84
23
|
}
|
|
85
24
|
});
|
|
86
25
|
|
|
@@ -798,6 +737,13 @@ var init_theme = __esm({
|
|
|
798
737
|
|
|
799
738
|
// libs/uipack/src/theme/css-to-theme.ts
|
|
800
739
|
function cssToTailwindTheme(userCss) {
|
|
740
|
+
if (userCss.length > MAX_CSS_INPUT_LENGTH) {
|
|
741
|
+
return {
|
|
742
|
+
themeBlock: "",
|
|
743
|
+
remainingCss: userCss,
|
|
744
|
+
colorVars: /* @__PURE__ */ new Map()
|
|
745
|
+
};
|
|
746
|
+
}
|
|
801
747
|
const colorVars = /* @__PURE__ */ new Map();
|
|
802
748
|
const regex = new RegExp(COLOR_VAR_REGEX.source, "g");
|
|
803
749
|
let match;
|
|
@@ -830,11 +776,12 @@ function buildTailwindStyleBlock(userCss) {
|
|
|
830
776
|
${parts.join("\n\n")}
|
|
831
777
|
</style>`;
|
|
832
778
|
}
|
|
833
|
-
var COLOR_VAR_REGEX;
|
|
779
|
+
var COLOR_VAR_REGEX, MAX_CSS_INPUT_LENGTH;
|
|
834
780
|
var init_css_to_theme = __esm({
|
|
835
781
|
"libs/uipack/src/theme/css-to-theme.ts"() {
|
|
836
782
|
"use strict";
|
|
837
783
|
COLOR_VAR_REGEX = /--(color-[\w-]+):\s*([^;]+);/g;
|
|
784
|
+
MAX_CSS_INPUT_LENGTH = 1e5;
|
|
838
785
|
}
|
|
839
786
|
});
|
|
840
787
|
|
|
@@ -879,6 +826,9 @@ function isTemplateBuilderFunction(fn) {
|
|
|
879
826
|
return true;
|
|
880
827
|
}
|
|
881
828
|
function containsJsx(source) {
|
|
829
|
+
if (source.length > MAX_TEMPLATE_LENGTH) {
|
|
830
|
+
return false;
|
|
831
|
+
}
|
|
882
832
|
if (/<[A-Z][a-zA-Z0-9]*(\s|>|\/)/.test(source)) {
|
|
883
833
|
return true;
|
|
884
834
|
}
|
|
@@ -903,6 +853,9 @@ function containsJsx(source) {
|
|
|
903
853
|
return false;
|
|
904
854
|
}
|
|
905
855
|
function containsMdxSyntax(source) {
|
|
856
|
+
if (source.length > MAX_TEMPLATE_LENGTH) {
|
|
857
|
+
return false;
|
|
858
|
+
}
|
|
906
859
|
if (/<[A-Z][a-zA-Z0-9]*/.test(source)) {
|
|
907
860
|
return true;
|
|
908
861
|
}
|
|
@@ -976,9 +929,11 @@ function detectTemplateType(template) {
|
|
|
976
929
|
reason: "Unknown template type, defaulting to HTML"
|
|
977
930
|
};
|
|
978
931
|
}
|
|
932
|
+
var MAX_TEMPLATE_LENGTH;
|
|
979
933
|
var init_detect = __esm({
|
|
980
934
|
"libs/uipack/src/renderers/utils/detect.ts"() {
|
|
981
935
|
"use strict";
|
|
936
|
+
MAX_TEMPLATE_LENGTH = 5e4;
|
|
982
937
|
}
|
|
983
938
|
});
|
|
984
939
|
|
|
@@ -2417,9 +2372,9 @@ var init_renderers = __esm({
|
|
|
2417
2372
|
|
|
2418
2373
|
// libs/uipack/src/bundler/file-cache/hash-calculator.ts
|
|
2419
2374
|
import { createHash } from "crypto";
|
|
2420
|
-
import { readFile } from "fs/promises";
|
|
2421
2375
|
import { existsSync } from "fs";
|
|
2422
2376
|
import { join as join2, dirname, resolve } from "path";
|
|
2377
|
+
import { readFile, readFileBuffer } from "@frontmcp/utils";
|
|
2423
2378
|
function sha256(content) {
|
|
2424
2379
|
return createHash("sha256").update(content, "utf8").digest("hex");
|
|
2425
2380
|
}
|
|
@@ -2428,7 +2383,7 @@ function sha256Buffer(buffer) {
|
|
|
2428
2383
|
}
|
|
2429
2384
|
async function hashFile(filePath) {
|
|
2430
2385
|
try {
|
|
2431
|
-
const content = await
|
|
2386
|
+
const content = await readFileBuffer(filePath);
|
|
2432
2387
|
return sha256Buffer(content);
|
|
2433
2388
|
} catch {
|
|
2434
2389
|
return void 0;
|
|
@@ -2479,7 +2434,7 @@ async function collectLocalDependencies(filePath, baseDir, collected, maxDepth,
|
|
|
2479
2434
|
if (!existsSync(filePath)) return;
|
|
2480
2435
|
collected.add(filePath);
|
|
2481
2436
|
try {
|
|
2482
|
-
const content = await readFile(filePath
|
|
2437
|
+
const content = await readFile(filePath);
|
|
2483
2438
|
const imports = extractImportPaths(content);
|
|
2484
2439
|
for (const importPath of imports) {
|
|
2485
2440
|
if (!importPath.startsWith(".") && !importPath.startsWith("/")) {
|
|
@@ -3397,7 +3352,10 @@ function generateUMDShim(dependencies, options = {}) {
|
|
|
3397
3352
|
console.warn('UMD shim failed:', e);
|
|
3398
3353
|
}
|
|
3399
3354
|
})();` : `window.__esm_shim = ${shimObject};`;
|
|
3400
|
-
|
|
3355
|
+
if (minify && code.length <= 1e5) {
|
|
3356
|
+
return code.replace(/\s+/g, " ").replace(/\s*([{},:])\s*/g, "$1");
|
|
3357
|
+
}
|
|
3358
|
+
return code;
|
|
3401
3359
|
}
|
|
3402
3360
|
function generateCDNScriptTags(dependencies) {
|
|
3403
3361
|
return dependencies.filter((dep) => !dep.esm).map((dep) => {
|
|
@@ -3696,10 +3654,10 @@ __export(filesystem_exports, {
|
|
|
3696
3654
|
StorageNotInitializedError: () => StorageNotInitializedError,
|
|
3697
3655
|
createFilesystemStorage: () => createFilesystemStorage
|
|
3698
3656
|
});
|
|
3699
|
-
import { mkdir, readFile as readFile2, writeFile, readdir, unlink, rm } from "fs/promises";
|
|
3700
3657
|
import { join as join3, dirname as dirname2 } from "path";
|
|
3701
3658
|
import { existsSync as existsSync2 } from "fs";
|
|
3702
3659
|
import { createHash as createHash3 } from "crypto";
|
|
3660
|
+
import { mkdir, readFile as readFile2, writeFile, readdir, unlink, rm } from "@frontmcp/utils";
|
|
3703
3661
|
function createFilesystemStorage(options) {
|
|
3704
3662
|
return new FilesystemStorage(options);
|
|
3705
3663
|
}
|
|
@@ -3935,7 +3893,7 @@ var init_filesystem = __esm({
|
|
|
3935
3893
|
*/
|
|
3936
3894
|
async writeEntry(filePath, entry) {
|
|
3937
3895
|
await mkdir(dirname2(filePath), { recursive: true });
|
|
3938
|
-
await writeFile(filePath, JSON.stringify(entry, null, 2)
|
|
3896
|
+
await writeFile(filePath, JSON.stringify(entry, null, 2));
|
|
3939
3897
|
}
|
|
3940
3898
|
/**
|
|
3941
3899
|
* Ensure the storage is initialized.
|
|
@@ -4292,10 +4250,10 @@ var init_redis = __esm({
|
|
|
4292
4250
|
});
|
|
4293
4251
|
|
|
4294
4252
|
// libs/uipack/src/bundler/file-cache/component-builder.ts
|
|
4295
|
-
import { readFile as readFile3 } from "fs/promises";
|
|
4296
4253
|
import { existsSync as existsSync3 } from "fs";
|
|
4297
4254
|
import { resolve as resolve2, extname, basename } from "path";
|
|
4298
4255
|
import { randomUUID } from "crypto";
|
|
4256
|
+
import { readFile as readFile3 } from "@frontmcp/utils";
|
|
4299
4257
|
async function createFilesystemBuilder(cacheDir = ".frontmcp-cache/builds") {
|
|
4300
4258
|
const { FilesystemStorage: FilesystemStorage2 } = await Promise.resolve().then(() => (init_filesystem(), filesystem_exports));
|
|
4301
4259
|
const storage = new FilesystemStorage2({ cacheDir });
|
|
@@ -4658,16 +4616,13 @@ function buildUIMeta(options) {
|
|
|
4658
4616
|
case "generic-mcp":
|
|
4659
4617
|
case "gemini":
|
|
4660
4618
|
default:
|
|
4661
|
-
meta["frontmcp/html"] = html;
|
|
4662
|
-
meta["frontmcp/mimeType"] = "text/html+mcp";
|
|
4663
|
-
if (rendererType) meta["frontmcp/type"] = rendererType;
|
|
4664
|
-
if (contentHash) meta["frontmcp/contentHash"] = contentHash;
|
|
4665
|
-
if (manifestUri) meta["frontmcp/manifestUri"] = manifestUri;
|
|
4666
|
-
if (token) meta["frontmcp/widgetToken"] = token;
|
|
4667
|
-
if (directUrl) meta["frontmcp/directUrl"] = directUrl;
|
|
4668
4619
|
meta["ui/html"] = html;
|
|
4669
4620
|
meta["ui/mimeType"] = "text/html+mcp";
|
|
4670
4621
|
if (rendererType) meta["ui/type"] = rendererType;
|
|
4622
|
+
if (contentHash) meta["ui/contentHash"] = contentHash;
|
|
4623
|
+
if (manifestUri) meta["ui/manifestUri"] = manifestUri;
|
|
4624
|
+
if (token) meta["ui/widgetToken"] = token;
|
|
4625
|
+
if (directUrl) meta["ui/directUrl"] = directUrl;
|
|
4671
4626
|
if (platformType === "claude") {
|
|
4672
4627
|
return buildClaudeMeta(meta, uiConfig);
|
|
4673
4628
|
} else if (platformType === "gemini") {
|
|
@@ -4726,34 +4681,37 @@ function buildIDEMeta(meta, uiConfig) {
|
|
|
4726
4681
|
}
|
|
4727
4682
|
return meta;
|
|
4728
4683
|
}
|
|
4729
|
-
function buildFrontMCPCSP(csp) {
|
|
4730
|
-
const result = {};
|
|
4731
|
-
if (csp.connectDomains?.length) {
|
|
4732
|
-
result.connectDomains = csp.connectDomains;
|
|
4733
|
-
}
|
|
4734
|
-
if (csp.resourceDomains?.length) {
|
|
4735
|
-
result.resourceDomains = csp.resourceDomains;
|
|
4736
|
-
}
|
|
4737
|
-
return result;
|
|
4738
|
-
}
|
|
4739
4684
|
function buildGenericMeta(meta, uiConfig) {
|
|
4740
|
-
if (uiConfig.widgetAccessible) {
|
|
4741
|
-
meta["frontmcp/widgetAccessible"] = true;
|
|
4742
|
-
}
|
|
4743
4685
|
if (uiConfig.csp) {
|
|
4744
|
-
|
|
4686
|
+
const csp = {};
|
|
4687
|
+
if (uiConfig.csp.connectDomains?.length) {
|
|
4688
|
+
csp.connectDomains = uiConfig.csp.connectDomains;
|
|
4689
|
+
}
|
|
4690
|
+
if (uiConfig.csp.resourceDomains?.length) {
|
|
4691
|
+
csp.resourceDomains = uiConfig.csp.resourceDomains;
|
|
4692
|
+
}
|
|
4693
|
+
if (Object.keys(csp).length > 0) {
|
|
4694
|
+
meta["ui/csp"] = csp;
|
|
4695
|
+
}
|
|
4745
4696
|
}
|
|
4746
4697
|
if (uiConfig.displayMode) {
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4698
|
+
const displayModeMap = {
|
|
4699
|
+
inline: "inline",
|
|
4700
|
+
fullscreen: "fullscreen",
|
|
4701
|
+
pip: "pip",
|
|
4702
|
+
widget: "inline",
|
|
4703
|
+
panel: "fullscreen"
|
|
4704
|
+
};
|
|
4705
|
+
const mappedMode = displayModeMap[uiConfig.displayMode];
|
|
4706
|
+
if (mappedMode) {
|
|
4707
|
+
meta["ui/displayMode"] = mappedMode;
|
|
4708
|
+
}
|
|
4751
4709
|
}
|
|
4752
4710
|
if (uiConfig.prefersBorder !== void 0) {
|
|
4753
|
-
meta["
|
|
4711
|
+
meta["ui/prefersBorder"] = uiConfig.prefersBorder;
|
|
4754
4712
|
}
|
|
4755
4713
|
if (uiConfig.sandboxDomain) {
|
|
4756
|
-
meta["
|
|
4714
|
+
meta["ui/domain"] = uiConfig.sandboxDomain;
|
|
4757
4715
|
}
|
|
4758
4716
|
return meta;
|
|
4759
4717
|
}
|
|
@@ -5005,12 +4963,22 @@ function buildToolResponseContent(options) {
|
|
|
5005
4963
|
}
|
|
5006
4964
|
if (useStructuredContent) {
|
|
5007
4965
|
if (htmlContent) {
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
4966
|
+
const htmlInContent = platformType === "openai" || platformType === "ext-apps";
|
|
4967
|
+
if (htmlInContent) {
|
|
4968
|
+
return {
|
|
4969
|
+
content: [{ type: "text", text: htmlContent }],
|
|
4970
|
+
structuredContent: rawOutput,
|
|
4971
|
+
contentCleared: false,
|
|
4972
|
+
format: "structured-content"
|
|
4973
|
+
};
|
|
4974
|
+
} else {
|
|
4975
|
+
return {
|
|
4976
|
+
content: [{ type: "text", text: safeStringify(rawOutput) }],
|
|
4977
|
+
structuredContent: rawOutput,
|
|
4978
|
+
contentCleared: false,
|
|
4979
|
+
format: "structured-content"
|
|
4980
|
+
};
|
|
4981
|
+
}
|
|
5014
4982
|
}
|
|
5015
4983
|
return {
|
|
5016
4984
|
content: [{ type: "text", text: safeStringify(rawOutput) }],
|
|
@@ -5882,7 +5850,11 @@ FrontMcpBridge.prototype._setupDataToolCallHandler = function() {
|
|
|
5882
5850
|
};
|
|
5883
5851
|
`.trim();
|
|
5884
5852
|
}
|
|
5853
|
+
var MAX_MINIFY_CODE_LENGTH = 5e5;
|
|
5885
5854
|
function minifyJS(code) {
|
|
5855
|
+
if (code.length > MAX_MINIFY_CODE_LENGTH) {
|
|
5856
|
+
return code;
|
|
5857
|
+
}
|
|
5886
5858
|
return code.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "").replace(/\s+/g, " ").replace(/\s*([{};,:()[\]])\s*/g, "$1").replace(/;\}/g, "}").trim();
|
|
5887
5859
|
}
|
|
5888
5860
|
function generatePlatformBundle(platform, options = {}) {
|
|
@@ -6522,7 +6494,11 @@ function detectPIIType(value) {
|
|
|
6522
6494
|
if (isIPv4(value)) return "IP";
|
|
6523
6495
|
return null;
|
|
6524
6496
|
}
|
|
6497
|
+
var MAX_PII_TEXT_LENGTH = 1e5;
|
|
6525
6498
|
function redactPIIFromText(text) {
|
|
6499
|
+
if (text.length > MAX_PII_TEXT_LENGTH) {
|
|
6500
|
+
return text;
|
|
6501
|
+
}
|
|
6526
6502
|
let result = text;
|
|
6527
6503
|
result = result.replace(PII_PATTERNS.creditCardInText, REDACTION_TOKENS.CARD);
|
|
6528
6504
|
result = result.replace(PII_PATTERNS.ssnInText, REDACTION_TOKENS.ID);
|
|
@@ -8507,7 +8483,7 @@ function describeZodType(schema) {
|
|
|
8507
8483
|
}
|
|
8508
8484
|
|
|
8509
8485
|
// libs/uipack/src/validation/template-validator.ts
|
|
8510
|
-
|
|
8486
|
+
init_handlebars();
|
|
8511
8487
|
function validateTemplate(template, outputSchema, options = {}) {
|
|
8512
8488
|
const { inputSchema, warnOnOptional = true, suggestSimilar = true, maxSuggestionDistance = 3 } = options;
|
|
8513
8489
|
const errors = [];
|
|
@@ -11203,13 +11179,12 @@ var GenericPreview = class {
|
|
|
11203
11179
|
forDiscoveryStatic(result, toolName, _description) {
|
|
11204
11180
|
const resourceUri = `resource://widget/${toolName}`;
|
|
11205
11181
|
const _meta = {
|
|
11206
|
-
//
|
|
11207
|
-
"
|
|
11208
|
-
"
|
|
11209
|
-
|
|
11210
|
-
|
|
11182
|
+
// Use ui/* namespace for generic MCP clients
|
|
11183
|
+
"ui/resourceUri": resourceUri,
|
|
11184
|
+
"ui/widgetCSP": {
|
|
11185
|
+
connectDomains: ["esm.sh", "cdn.tailwindcss.com"],
|
|
11186
|
+
resourceDomains: ["esm.sh", "cdn.tailwindcss.com", "fonts.googleapis.com", "fonts.gstatic.com"]
|
|
11211
11187
|
},
|
|
11212
|
-
// Fallback for compatibility
|
|
11213
11188
|
"ui/mimeType": "text/html+mcp"
|
|
11214
11189
|
};
|
|
11215
11190
|
return {
|
|
@@ -11220,10 +11195,11 @@ var GenericPreview = class {
|
|
|
11220
11195
|
}
|
|
11221
11196
|
forDiscoveryHybrid(result, _toolName, _description) {
|
|
11222
11197
|
const _meta = {
|
|
11223
|
-
|
|
11224
|
-
"
|
|
11225
|
-
|
|
11226
|
-
|
|
11198
|
+
// Use ui/* namespace for generic MCP clients
|
|
11199
|
+
"ui/resourceUri": result.shellResourceUri,
|
|
11200
|
+
"ui/widgetCSP": {
|
|
11201
|
+
connectDomains: ["esm.sh", "cdn.tailwindcss.com"],
|
|
11202
|
+
resourceDomains: ["esm.sh", "cdn.tailwindcss.com", "fonts.googleapis.com", "fonts.gstatic.com"]
|
|
11227
11203
|
},
|
|
11228
11204
|
"ui/mimeType": "text/html+mcp"
|
|
11229
11205
|
};
|
|
@@ -11235,7 +11211,7 @@ var GenericPreview = class {
|
|
|
11235
11211
|
}
|
|
11236
11212
|
forDiscoveryInline(result, _toolName, _description) {
|
|
11237
11213
|
const _meta = {
|
|
11238
|
-
|
|
11214
|
+
// Use ui/* namespace for generic MCP clients
|
|
11239
11215
|
"ui/html": result.loaderShell,
|
|
11240
11216
|
"ui/mimeType": "text/html+mcp"
|
|
11241
11217
|
};
|
|
@@ -11251,7 +11227,6 @@ var GenericPreview = class {
|
|
|
11251
11227
|
const html = this.injectBuilderMode(result.html, input, output, mockData);
|
|
11252
11228
|
return {
|
|
11253
11229
|
_meta: {
|
|
11254
|
-
"frontmcp/html": html,
|
|
11255
11230
|
"ui/html": html
|
|
11256
11231
|
},
|
|
11257
11232
|
html,
|
|
@@ -11267,13 +11242,12 @@ var GenericPreview = class {
|
|
|
11267
11242
|
}
|
|
11268
11243
|
forExecutionHybrid(result, input, output, builderMode, mockData) {
|
|
11269
11244
|
const _meta = {
|
|
11270
|
-
"
|
|
11245
|
+
"ui/component": result.componentChunk
|
|
11271
11246
|
};
|
|
11272
11247
|
if (builderMode) {
|
|
11273
11248
|
const html = this.combineHybridForBuilder(result, input, output, mockData);
|
|
11274
11249
|
return {
|
|
11275
11250
|
_meta: {
|
|
11276
|
-
"frontmcp/html": html,
|
|
11277
11251
|
"ui/html": html
|
|
11278
11252
|
},
|
|
11279
11253
|
html,
|
|
@@ -11289,7 +11263,6 @@ var GenericPreview = class {
|
|
|
11289
11263
|
}
|
|
11290
11264
|
forExecutionInline(result, input, output, _builderMode, _mockData) {
|
|
11291
11265
|
const _meta = {
|
|
11292
|
-
"frontmcp/html": "<!-- Full widget will be generated -->",
|
|
11293
11266
|
"ui/html": "<!-- Full widget will be generated -->"
|
|
11294
11267
|
};
|
|
11295
11268
|
return {
|
|
@@ -12474,7 +12447,11 @@ init_renderers();
|
|
|
12474
12447
|
import { createHash as createHash2 } from "crypto";
|
|
12475
12448
|
|
|
12476
12449
|
// libs/uipack/src/registry/render-template.ts
|
|
12450
|
+
var MAX_MDX_SOURCE_LENGTH = 1e5;
|
|
12477
12451
|
function containsMdxSyntax2(source) {
|
|
12452
|
+
if (source.length > MAX_MDX_SOURCE_LENGTH) {
|
|
12453
|
+
return false;
|
|
12454
|
+
}
|
|
12478
12455
|
if (/<[A-Z][a-zA-Z0-9]*/.test(source)) {
|
|
12479
12456
|
return true;
|
|
12480
12457
|
}
|
|
@@ -13317,7 +13294,11 @@ function getSubpathFromSpecifier(specifier) {
|
|
|
13317
13294
|
}
|
|
13318
13295
|
return void 0;
|
|
13319
13296
|
}
|
|
13297
|
+
var MAX_IMPORT_STATEMENT_LENGTH = 2e3;
|
|
13320
13298
|
function parseImportStatement(statement) {
|
|
13299
|
+
if (statement.length > MAX_IMPORT_STATEMENT_LENGTH) {
|
|
13300
|
+
return null;
|
|
13301
|
+
}
|
|
13321
13302
|
const namedMatch = /import\s+(?:\{[^}]*\}|\*\s+as\s+\w+|\w+)\s+from\s+['"]([^'"]+)['"]/.exec(statement);
|
|
13322
13303
|
if (namedMatch) {
|
|
13323
13304
|
return namedMatch[1];
|
package/esm/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontmcp/uipack",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.2",
|
|
4
4
|
"description": "FrontMCP UIpack - Bundling, build tools, and platform adapters for MCP UI development (React-free core)",
|
|
5
5
|
"author": "AgentFront <info@agentfront.dev>",
|
|
6
6
|
"homepage": "https://docs.agentfront.dev",
|
|
@@ -55,8 +55,9 @@
|
|
|
55
55
|
"./esm": null
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
+
"@frontmcp/utils": "0.7.2",
|
|
58
59
|
"@swc/core": "^1.5.0",
|
|
59
|
-
"enclave-vm": "^
|
|
60
|
+
"enclave-vm": "^2.7.0",
|
|
60
61
|
"esbuild": "^0.27.1",
|
|
61
62
|
"handlebars": "^4.7.8",
|
|
62
63
|
"zod": "^4.0.0"
|
package/esm/registry/index.mjs
CHANGED
|
@@ -548,31 +548,18 @@ var init_theme2 = __esm({
|
|
|
548
548
|
}
|
|
549
549
|
});
|
|
550
550
|
|
|
551
|
-
// libs/uipack/src/utils/escape-html.ts
|
|
552
|
-
function escapeHtml(str) {
|
|
553
|
-
if (str === null || str === void 0) {
|
|
554
|
-
return "";
|
|
555
|
-
}
|
|
556
|
-
const s = String(str);
|
|
557
|
-
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
558
|
-
}
|
|
559
|
-
function escapeJsString(str) {
|
|
560
|
-
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");
|
|
561
|
-
}
|
|
562
|
-
function escapeScriptClose(jsonString) {
|
|
563
|
-
return jsonString.replace(/<\//g, "<\\/");
|
|
564
|
-
}
|
|
565
|
-
var init_escape_html = __esm({
|
|
566
|
-
"libs/uipack/src/utils/escape-html.ts"() {
|
|
567
|
-
"use strict";
|
|
568
|
-
}
|
|
569
|
-
});
|
|
570
|
-
|
|
571
551
|
// libs/uipack/src/utils/index.ts
|
|
552
|
+
import {
|
|
553
|
+
safeStringify,
|
|
554
|
+
escapeHtml,
|
|
555
|
+
escapeHtmlAttr,
|
|
556
|
+
escapeJsString,
|
|
557
|
+
escapeScriptClose,
|
|
558
|
+
safeJsonForScript
|
|
559
|
+
} from "@frontmcp/utils";
|
|
572
560
|
var init_utils = __esm({
|
|
573
561
|
"libs/uipack/src/utils/index.ts"() {
|
|
574
562
|
"use strict";
|
|
575
|
-
init_escape_html();
|
|
576
563
|
}
|
|
577
564
|
});
|
|
578
565
|
|
|
@@ -826,6 +813,9 @@ function isTemplateBuilderFunction(fn) {
|
|
|
826
813
|
return true;
|
|
827
814
|
}
|
|
828
815
|
function containsJsx(source) {
|
|
816
|
+
if (source.length > MAX_TEMPLATE_LENGTH) {
|
|
817
|
+
return false;
|
|
818
|
+
}
|
|
829
819
|
if (/<[A-Z][a-zA-Z0-9]*(\s|>|\/)/.test(source)) {
|
|
830
820
|
return true;
|
|
831
821
|
}
|
|
@@ -850,6 +840,9 @@ function containsJsx(source) {
|
|
|
850
840
|
return false;
|
|
851
841
|
}
|
|
852
842
|
function containsMdxSyntax(source) {
|
|
843
|
+
if (source.length > MAX_TEMPLATE_LENGTH) {
|
|
844
|
+
return false;
|
|
845
|
+
}
|
|
853
846
|
if (/<[A-Z][a-zA-Z0-9]*/.test(source)) {
|
|
854
847
|
return true;
|
|
855
848
|
}
|
|
@@ -923,9 +916,11 @@ function detectTemplateType(template) {
|
|
|
923
916
|
reason: "Unknown template type, defaulting to HTML"
|
|
924
917
|
};
|
|
925
918
|
}
|
|
919
|
+
var MAX_TEMPLATE_LENGTH;
|
|
926
920
|
var init_detect = __esm({
|
|
927
921
|
"libs/uipack/src/renderers/utils/detect.ts"() {
|
|
928
922
|
"use strict";
|
|
923
|
+
MAX_TEMPLATE_LENGTH = 5e4;
|
|
929
924
|
}
|
|
930
925
|
});
|
|
931
926
|
|
|
@@ -2143,6 +2138,7 @@ var init_renderers = __esm({
|
|
|
2143
2138
|
|
|
2144
2139
|
// libs/uipack/src/bundler/file-cache/hash-calculator.ts
|
|
2145
2140
|
import { createHash } from "crypto";
|
|
2141
|
+
import { readFile, readFileBuffer } from "@frontmcp/utils";
|
|
2146
2142
|
function sha256(content) {
|
|
2147
2143
|
return createHash("sha256").update(content, "utf8").digest("hex");
|
|
2148
2144
|
}
|
|
@@ -2980,7 +2976,11 @@ FrontMcpBridge.prototype._setupDataToolCallHandler = function() {
|
|
|
2980
2976
|
};
|
|
2981
2977
|
`.trim();
|
|
2982
2978
|
}
|
|
2979
|
+
var MAX_MINIFY_CODE_LENGTH = 5e5;
|
|
2983
2980
|
function minifyJS(code) {
|
|
2981
|
+
if (code.length > MAX_MINIFY_CODE_LENGTH) {
|
|
2982
|
+
return code;
|
|
2983
|
+
}
|
|
2984
2984
|
return code.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "").replace(/\s+/g, " ").replace(/\s*([{};,:()[\]])\s*/g, "$1").replace(/;\}/g, "}").trim();
|
|
2985
2985
|
}
|
|
2986
2986
|
function generatePlatformBundle(platform, options = {}) {
|
|
@@ -4422,7 +4422,11 @@ function wrapStaticWidgetUniversal(options) {
|
|
|
4422
4422
|
}
|
|
4423
4423
|
|
|
4424
4424
|
// libs/uipack/src/registry/render-template.ts
|
|
4425
|
+
var MAX_MDX_SOURCE_LENGTH = 1e5;
|
|
4425
4426
|
function containsMdxSyntax2(source) {
|
|
4427
|
+
if (source.length > MAX_MDX_SOURCE_LENGTH) {
|
|
4428
|
+
return false;
|
|
4429
|
+
}
|
|
4426
4430
|
if (/<[A-Z][a-zA-Z0-9]*/.test(source)) {
|
|
4427
4431
|
return true;
|
|
4428
4432
|
}
|
|
@@ -4590,16 +4594,13 @@ function buildUIMeta(options) {
|
|
|
4590
4594
|
case "generic-mcp":
|
|
4591
4595
|
case "gemini":
|
|
4592
4596
|
default:
|
|
4593
|
-
meta["frontmcp/html"] = html;
|
|
4594
|
-
meta["frontmcp/mimeType"] = "text/html+mcp";
|
|
4595
|
-
if (rendererType) meta["frontmcp/type"] = rendererType;
|
|
4596
|
-
if (contentHash) meta["frontmcp/contentHash"] = contentHash;
|
|
4597
|
-
if (manifestUri) meta["frontmcp/manifestUri"] = manifestUri;
|
|
4598
|
-
if (token) meta["frontmcp/widgetToken"] = token;
|
|
4599
|
-
if (directUrl) meta["frontmcp/directUrl"] = directUrl;
|
|
4600
4597
|
meta["ui/html"] = html;
|
|
4601
4598
|
meta["ui/mimeType"] = "text/html+mcp";
|
|
4602
4599
|
if (rendererType) meta["ui/type"] = rendererType;
|
|
4600
|
+
if (contentHash) meta["ui/contentHash"] = contentHash;
|
|
4601
|
+
if (manifestUri) meta["ui/manifestUri"] = manifestUri;
|
|
4602
|
+
if (token) meta["ui/widgetToken"] = token;
|
|
4603
|
+
if (directUrl) meta["ui/directUrl"] = directUrl;
|
|
4603
4604
|
if (platformType === "claude") {
|
|
4604
4605
|
return buildClaudeMeta(meta, uiConfig);
|
|
4605
4606
|
} else if (platformType === "gemini") {
|
|
@@ -4648,34 +4649,37 @@ function buildIDEMeta(meta, uiConfig) {
|
|
|
4648
4649
|
}
|
|
4649
4650
|
return meta;
|
|
4650
4651
|
}
|
|
4651
|
-
function buildFrontMCPCSP(csp) {
|
|
4652
|
-
const result = {};
|
|
4653
|
-
if (csp.connectDomains?.length) {
|
|
4654
|
-
result.connectDomains = csp.connectDomains;
|
|
4655
|
-
}
|
|
4656
|
-
if (csp.resourceDomains?.length) {
|
|
4657
|
-
result.resourceDomains = csp.resourceDomains;
|
|
4658
|
-
}
|
|
4659
|
-
return result;
|
|
4660
|
-
}
|
|
4661
4652
|
function buildGenericMeta(meta, uiConfig) {
|
|
4662
|
-
if (uiConfig.widgetAccessible) {
|
|
4663
|
-
meta["frontmcp/widgetAccessible"] = true;
|
|
4664
|
-
}
|
|
4665
4653
|
if (uiConfig.csp) {
|
|
4666
|
-
|
|
4654
|
+
const csp = {};
|
|
4655
|
+
if (uiConfig.csp.connectDomains?.length) {
|
|
4656
|
+
csp.connectDomains = uiConfig.csp.connectDomains;
|
|
4657
|
+
}
|
|
4658
|
+
if (uiConfig.csp.resourceDomains?.length) {
|
|
4659
|
+
csp.resourceDomains = uiConfig.csp.resourceDomains;
|
|
4660
|
+
}
|
|
4661
|
+
if (Object.keys(csp).length > 0) {
|
|
4662
|
+
meta["ui/csp"] = csp;
|
|
4663
|
+
}
|
|
4667
4664
|
}
|
|
4668
4665
|
if (uiConfig.displayMode) {
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4666
|
+
const displayModeMap = {
|
|
4667
|
+
inline: "inline",
|
|
4668
|
+
fullscreen: "fullscreen",
|
|
4669
|
+
pip: "pip",
|
|
4670
|
+
widget: "inline",
|
|
4671
|
+
panel: "fullscreen"
|
|
4672
|
+
};
|
|
4673
|
+
const mappedMode = displayModeMap[uiConfig.displayMode];
|
|
4674
|
+
if (mappedMode) {
|
|
4675
|
+
meta["ui/displayMode"] = mappedMode;
|
|
4676
|
+
}
|
|
4673
4677
|
}
|
|
4674
4678
|
if (uiConfig.prefersBorder !== void 0) {
|
|
4675
|
-
meta["
|
|
4679
|
+
meta["ui/prefersBorder"] = uiConfig.prefersBorder;
|
|
4676
4680
|
}
|
|
4677
4681
|
if (uiConfig.sandboxDomain) {
|
|
4678
|
-
meta["
|
|
4682
|
+
meta["ui/domain"] = uiConfig.sandboxDomain;
|
|
4679
4683
|
}
|
|
4680
4684
|
return meta;
|
|
4681
4685
|
}
|
|
@@ -4949,7 +4953,7 @@ function getSchemaPathStrings(schema, prefix = "output") {
|
|
|
4949
4953
|
}
|
|
4950
4954
|
|
|
4951
4955
|
// libs/uipack/src/validation/template-validator.ts
|
|
4952
|
-
|
|
4956
|
+
init_handlebars();
|
|
4953
4957
|
function validateTemplate(template, outputSchema, options = {}) {
|
|
4954
4958
|
const { inputSchema, warnOnOptional = true, suggestSimilar = true, maxSuggestionDistance = 3 } = options;
|
|
4955
4959
|
const errors = [];
|