@frontmcp/uipack 1.8.1 → 1.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -11
- package/adapters/index.js +72 -29
- package/adapters/template-renderer.d.ts +11 -1
- package/adapters/template-renderer.d.ts.map +1 -1
- package/esm/adapters/index.mjs +72 -29
- package/esm/index.mjs +75 -29
- package/esm/package.json +2 -2
- package/esm/shell/index.mjs +41 -13
- package/index.d.ts +1 -1
- package/index.d.ts.map +1 -1
- package/index.js +78 -29
- package/package.json +2 -2
- package/shell/data-injector.d.ts +5 -0
- package/shell/data-injector.d.ts.map +1 -1
- package/shell/index.d.ts +1 -0
- package/shell/index.d.ts.map +1 -1
- package/shell/index.js +44 -13
- package/shell/trusted-html.d.ts +40 -0
- package/shell/trusted-html.d.ts.map +1 -0
- package/types/ui-config.d.ts +30 -2
- package/types/ui-config.d.ts.map +1 -1
package/esm/index.mjs
CHANGED
|
@@ -2917,6 +2917,29 @@ function validateShellTemplate(template) {
|
|
|
2917
2917
|
};
|
|
2918
2918
|
}
|
|
2919
2919
|
|
|
2920
|
+
// libs/uipack/src/shell/trusted-html.ts
|
|
2921
|
+
var TRUSTED_HTML = /* @__PURE__ */ Symbol.for("@frontmcp/uipack/trusted-html");
|
|
2922
|
+
function trustedHtml(markup) {
|
|
2923
|
+
const value = String(markup);
|
|
2924
|
+
return Object.freeze({ [TRUSTED_HTML]: value, toString: () => value });
|
|
2925
|
+
}
|
|
2926
|
+
function isTrustedHtml(value) {
|
|
2927
|
+
return typeof value === "object" && value !== null && typeof value[TRUSTED_HTML] === "string";
|
|
2928
|
+
}
|
|
2929
|
+
function interpolate(value) {
|
|
2930
|
+
if (isTrustedHtml(value)) return value[TRUSTED_HTML];
|
|
2931
|
+
if (Array.isArray(value)) return value.map(interpolate).join("");
|
|
2932
|
+
if (value === false) return "";
|
|
2933
|
+
return escapeHtml(value);
|
|
2934
|
+
}
|
|
2935
|
+
function html(strings, ...values) {
|
|
2936
|
+
let markup = strings[0];
|
|
2937
|
+
for (let index = 0; index < values.length; index++) {
|
|
2938
|
+
markup += interpolate(values[index]) + strings[index + 1];
|
|
2939
|
+
}
|
|
2940
|
+
return trustedHtml(markup);
|
|
2941
|
+
}
|
|
2942
|
+
|
|
2920
2943
|
// libs/uipack/src/shell/data-injector.ts
|
|
2921
2944
|
function hasSizing(sizing) {
|
|
2922
2945
|
if (!sizing) return false;
|
|
@@ -2970,7 +2993,9 @@ function createTemplateHelpers() {
|
|
|
2970
2993
|
uniqueId: (prefix = "mcp") => {
|
|
2971
2994
|
return `${prefix}-${++_uniqueIdCounter}`;
|
|
2972
2995
|
},
|
|
2973
|
-
jsonEmbed: (data) => safeJsonForScript(data)
|
|
2996
|
+
jsonEmbed: (data) => safeJsonForScript(data),
|
|
2997
|
+
html,
|
|
2998
|
+
trustedHtml
|
|
2974
2999
|
};
|
|
2975
3000
|
}
|
|
2976
3001
|
|
|
@@ -3048,12 +3073,12 @@ function buildShell(content, config) {
|
|
|
3048
3073
|
sizing
|
|
3049
3074
|
});
|
|
3050
3075
|
if (!withShell) {
|
|
3051
|
-
const
|
|
3076
|
+
const html3 = `${dataScript}
|
|
3052
3077
|
${content}`;
|
|
3053
3078
|
return {
|
|
3054
|
-
html:
|
|
3055
|
-
hash: simpleHash(
|
|
3056
|
-
size: Buffer.byteLength(
|
|
3079
|
+
html: html3,
|
|
3080
|
+
hash: simpleHash(html3),
|
|
3081
|
+
size: Buffer.byteLength(html3, "utf-8")
|
|
3057
3082
|
};
|
|
3058
3083
|
}
|
|
3059
3084
|
if (customShell) {
|
|
@@ -3086,7 +3111,7 @@ ${content}`;
|
|
|
3086
3111
|
const bridgeScript = generateBridgeIIFE({ minify: true });
|
|
3087
3112
|
headParts.push(`<script>${bridgeScript}</script>`);
|
|
3088
3113
|
}
|
|
3089
|
-
const
|
|
3114
|
+
const html2 = `<!DOCTYPE html>
|
|
3090
3115
|
<html lang="en">
|
|
3091
3116
|
<head>
|
|
3092
3117
|
${headParts.map((p) => ` ${p}`).join("\n")}
|
|
@@ -3096,9 +3121,9 @@ ${content}
|
|
|
3096
3121
|
</body>
|
|
3097
3122
|
</html>`;
|
|
3098
3123
|
return {
|
|
3099
|
-
html,
|
|
3100
|
-
hash: simpleHash(
|
|
3101
|
-
size: Buffer.byteLength(
|
|
3124
|
+
html: html2,
|
|
3125
|
+
hash: simpleHash(html2),
|
|
3126
|
+
size: Buffer.byteLength(html2, "utf-8")
|
|
3102
3127
|
};
|
|
3103
3128
|
}
|
|
3104
3129
|
function buildCustomShell(content, customShell, ctx) {
|
|
@@ -3131,7 +3156,7 @@ ${sizingStyle}` : dataScript;
|
|
|
3131
3156
|
const bridgeScript = generateBridgeIIFE({ minify: true });
|
|
3132
3157
|
bridgeHtml = `<script>${bridgeScript}</script>`;
|
|
3133
3158
|
}
|
|
3134
|
-
const
|
|
3159
|
+
const html2 = applyShellTemplate(template, {
|
|
3135
3160
|
csp: cspTag,
|
|
3136
3161
|
data: dataWithSizing,
|
|
3137
3162
|
bridge: bridgeHtml,
|
|
@@ -3139,9 +3164,9 @@ ${sizingStyle}` : dataScript;
|
|
|
3139
3164
|
title: ctx.title ? escapeHtmlForTag(ctx.title) : ""
|
|
3140
3165
|
});
|
|
3141
3166
|
return {
|
|
3142
|
-
html,
|
|
3143
|
-
hash: simpleHash(
|
|
3144
|
-
size: Buffer.byteLength(
|
|
3167
|
+
html: html2,
|
|
3168
|
+
hash: simpleHash(html2),
|
|
3169
|
+
size: Buffer.byteLength(html2, "utf-8")
|
|
3145
3170
|
};
|
|
3146
3171
|
}
|
|
3147
3172
|
function simpleHash(str) {
|
|
@@ -3548,10 +3573,10 @@ function resolveFileSource(source, options = {}) {
|
|
|
3548
3573
|
};
|
|
3549
3574
|
}
|
|
3550
3575
|
function resolveFunctionSource(source, input, output) {
|
|
3551
|
-
const
|
|
3576
|
+
const html2 = source(input, output);
|
|
3552
3577
|
return {
|
|
3553
3578
|
mode: "inline",
|
|
3554
|
-
html,
|
|
3579
|
+
html: html2,
|
|
3555
3580
|
exportName: "default",
|
|
3556
3581
|
meta: { mcpAware: false, renderer: "html" },
|
|
3557
3582
|
peerDependencies: []
|
|
@@ -3997,11 +4022,29 @@ function buildCspConfig(resolver) {
|
|
|
3997
4022
|
}
|
|
3998
4023
|
return { resourceDomains: cspResourceDomains, connectDomains: cspConnectDomains };
|
|
3999
4024
|
}
|
|
4000
|
-
|
|
4025
|
+
var STRING_RESULT_DOCS = "https://docs.agentfront.dev/frontmcp/guides/building-tool-ui#trusted-markup";
|
|
4026
|
+
var noticedStringResultTools = /* @__PURE__ */ new Set();
|
|
4027
|
+
function noticeStringResult(toolName, logger) {
|
|
4028
|
+
if (noticedStringResultTools.has(toolName)) return;
|
|
4029
|
+
noticedStringResultTools.add(toolName);
|
|
4030
|
+
logger.warn(
|
|
4031
|
+
`[frontmcp] The UI template of tool "${toolName}" returned a plain string containing markup, which is rendered as HTML. FrontMCP 1.9 will HTML-escape plain string results by default. Build the markup with ctx.helpers.html\`\u2026\` (interpolated values are escaped) or wrap safe markup with ctx.helpers.trustedHtml(), then set ui.escapeStringResults: true (or escapeStringResults: false to keep the current behaviour without this notice). See ${STRING_RESULT_DOCS}`
|
|
4032
|
+
);
|
|
4033
|
+
}
|
|
4034
|
+
function renderUnwrappedResult(rawResult, options) {
|
|
4035
|
+
if (isTrustedHtml(rawResult)) {
|
|
4036
|
+
return String(rawResult);
|
|
4037
|
+
}
|
|
4001
4038
|
if (typeof rawResult !== "string") {
|
|
4002
4039
|
return `<pre>${escapeHtml(JSON.stringify(rawResult, null, 2))}</pre>`;
|
|
4003
4040
|
}
|
|
4004
|
-
|
|
4041
|
+
if (detectContentType(rawResult) !== "html" || options.escapeStringResults === true) {
|
|
4042
|
+
return escapeHtml(rawResult);
|
|
4043
|
+
}
|
|
4044
|
+
if (options.escapeStringResults === void 0) {
|
|
4045
|
+
noticeStringResult(options.toolName, options.logger ?? console);
|
|
4046
|
+
}
|
|
4047
|
+
return rawResult;
|
|
4005
4048
|
}
|
|
4006
4049
|
function renderToolTemplate(options) {
|
|
4007
4050
|
const { toolName, input, output, template, resolver, platformType, sizing } = options;
|
|
@@ -4015,7 +4058,7 @@ function renderToolTemplate(options) {
|
|
|
4015
4058
|
resolver,
|
|
4016
4059
|
sizing
|
|
4017
4060
|
};
|
|
4018
|
-
let
|
|
4061
|
+
let html2;
|
|
4019
4062
|
let hash = "";
|
|
4020
4063
|
let size = 0;
|
|
4021
4064
|
if (typeof template === "object" && template !== null && "file" in template) {
|
|
@@ -4024,43 +4067,43 @@ function renderToolTemplate(options) {
|
|
|
4024
4067
|
{ source: template, inlineReact: resourceMode === "inline" },
|
|
4025
4068
|
{ ...shellConfig, csp: cspConfig }
|
|
4026
4069
|
);
|
|
4027
|
-
|
|
4070
|
+
html2 = result.html;
|
|
4028
4071
|
hash = result.hash;
|
|
4029
4072
|
size = result.size;
|
|
4030
4073
|
} else if (typeof template === "function") {
|
|
4031
4074
|
if (uiType === "react") {
|
|
4032
4075
|
const shellResult = buildShell('<div id="root"></div>', shellConfig);
|
|
4033
|
-
|
|
4076
|
+
html2 = shellResult.html;
|
|
4034
4077
|
hash = shellResult.hash;
|
|
4035
4078
|
size = shellResult.size;
|
|
4036
4079
|
} else {
|
|
4037
4080
|
const helpers = createTemplateHelpers();
|
|
4038
4081
|
const ctx = { input, output, helpers };
|
|
4039
4082
|
const rawResult = template(ctx);
|
|
4040
|
-
const wrapped = wrapDetectedContent(rawResult);
|
|
4083
|
+
const wrapped = isTrustedHtml(rawResult) ? void 0 : wrapDetectedContent(rawResult);
|
|
4041
4084
|
if (wrapped) {
|
|
4042
|
-
|
|
4085
|
+
html2 = wrapped;
|
|
4043
4086
|
} else {
|
|
4044
|
-
const shellResult = buildShell(renderUnwrappedResult(rawResult), shellConfig);
|
|
4045
|
-
|
|
4087
|
+
const shellResult = buildShell(renderUnwrappedResult(rawResult, options), shellConfig);
|
|
4088
|
+
html2 = shellResult.html;
|
|
4046
4089
|
hash = shellResult.hash;
|
|
4047
4090
|
size = shellResult.size;
|
|
4048
4091
|
}
|
|
4049
4092
|
}
|
|
4050
4093
|
} else if (typeof template === "string") {
|
|
4051
4094
|
const shellResult = buildShell(template, shellConfig);
|
|
4052
|
-
|
|
4095
|
+
html2 = shellResult.html;
|
|
4053
4096
|
hash = shellResult.hash;
|
|
4054
4097
|
size = shellResult.size;
|
|
4055
4098
|
} else {
|
|
4056
4099
|
const shellResult = buildShell('<div id="root"></div>', shellConfig);
|
|
4057
|
-
|
|
4100
|
+
html2 = shellResult.html;
|
|
4058
4101
|
hash = shellResult.hash;
|
|
4059
4102
|
size = shellResult.size;
|
|
4060
4103
|
}
|
|
4061
4104
|
const htmlKey = "ui/html";
|
|
4062
4105
|
const meta = {
|
|
4063
|
-
[htmlKey]:
|
|
4106
|
+
[htmlKey]: html2,
|
|
4064
4107
|
"ui/type": uiType,
|
|
4065
4108
|
"ui/mimeType": MCP_APPS_MIME_TYPE
|
|
4066
4109
|
};
|
|
@@ -4071,10 +4114,10 @@ function renderToolTemplate(options) {
|
|
|
4071
4114
|
if (sizing.aspectRatio !== void 0) meta["ui/aspectRatio"] = sizing.aspectRatio;
|
|
4072
4115
|
}
|
|
4073
4116
|
return {
|
|
4074
|
-
html,
|
|
4117
|
+
html: html2,
|
|
4075
4118
|
uiType,
|
|
4076
4119
|
hash,
|
|
4077
|
-
size: size || Buffer.byteLength(
|
|
4120
|
+
size: size || Buffer.byteLength(html2, "utf8"),
|
|
4078
4121
|
meta
|
|
4079
4122
|
};
|
|
4080
4123
|
}
|
|
@@ -4217,6 +4260,7 @@ export {
|
|
|
4217
4260
|
getRegisteredPackages,
|
|
4218
4261
|
getSubpathFromSpecifier,
|
|
4219
4262
|
globalTypeCache,
|
|
4263
|
+
html,
|
|
4220
4264
|
isBundlingMode,
|
|
4221
4265
|
isDisplayMode,
|
|
4222
4266
|
isFileSource,
|
|
@@ -4229,6 +4273,7 @@ export {
|
|
|
4229
4273
|
isPackageRegistered,
|
|
4230
4274
|
isRelativeImport,
|
|
4231
4275
|
isResourceMode,
|
|
4276
|
+
isTrustedHtml,
|
|
4232
4277
|
isUIRenderFailure,
|
|
4233
4278
|
isUIType,
|
|
4234
4279
|
isUrlShellSource,
|
|
@@ -4248,6 +4293,7 @@ export {
|
|
|
4248
4293
|
safeStringify,
|
|
4249
4294
|
sanitizeCSPDomains,
|
|
4250
4295
|
transpileReactSource,
|
|
4296
|
+
trustedHtml,
|
|
4251
4297
|
validateCSPDomain,
|
|
4252
4298
|
validateImportMap,
|
|
4253
4299
|
validateShellTemplate,
|
package/esm/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontmcp/uipack",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.3",
|
|
4
4
|
"description": "FrontMCP UIpack - HTML shell builder, pluggable import resolver, and NPM component loader for MCP UI (React-free core)",
|
|
5
5
|
"author": "AgentFront <info@agentfront.dev>",
|
|
6
6
|
"homepage": "https://docs.agentfront.dev",
|
|
@@ -61,6 +61,6 @@
|
|
|
61
61
|
"typescript": "^5.9.3"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
|
-
"@frontmcp/lazy-zod": "1.8.
|
|
64
|
+
"@frontmcp/lazy-zod": "1.8.3"
|
|
65
65
|
}
|
|
66
66
|
}
|
package/esm/shell/index.mjs
CHANGED
|
@@ -1343,6 +1343,29 @@ function safeJsonForScript(value) {
|
|
|
1343
1343
|
}
|
|
1344
1344
|
}
|
|
1345
1345
|
|
|
1346
|
+
// libs/uipack/src/shell/trusted-html.ts
|
|
1347
|
+
var TRUSTED_HTML = /* @__PURE__ */ Symbol.for("@frontmcp/uipack/trusted-html");
|
|
1348
|
+
function trustedHtml(markup) {
|
|
1349
|
+
const value = String(markup);
|
|
1350
|
+
return Object.freeze({ [TRUSTED_HTML]: value, toString: () => value });
|
|
1351
|
+
}
|
|
1352
|
+
function isTrustedHtml(value) {
|
|
1353
|
+
return typeof value === "object" && value !== null && typeof value[TRUSTED_HTML] === "string";
|
|
1354
|
+
}
|
|
1355
|
+
function interpolate(value) {
|
|
1356
|
+
if (isTrustedHtml(value)) return value[TRUSTED_HTML];
|
|
1357
|
+
if (Array.isArray(value)) return value.map(interpolate).join("");
|
|
1358
|
+
if (value === false) return "";
|
|
1359
|
+
return escapeHtml(value);
|
|
1360
|
+
}
|
|
1361
|
+
function html(strings, ...values) {
|
|
1362
|
+
let markup = strings[0];
|
|
1363
|
+
for (let index = 0; index < values.length; index++) {
|
|
1364
|
+
markup += interpolate(values[index]) + strings[index + 1];
|
|
1365
|
+
}
|
|
1366
|
+
return trustedHtml(markup);
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1346
1369
|
// libs/uipack/src/shell/data-injector.ts
|
|
1347
1370
|
function hasSizing(sizing) {
|
|
1348
1371
|
if (!sizing) return false;
|
|
@@ -1396,7 +1419,9 @@ function createTemplateHelpers() {
|
|
|
1396
1419
|
uniqueId: (prefix = "mcp") => {
|
|
1397
1420
|
return `${prefix}-${++_uniqueIdCounter}`;
|
|
1398
1421
|
},
|
|
1399
|
-
jsonEmbed: (data) => safeJsonForScript(data)
|
|
1422
|
+
jsonEmbed: (data) => safeJsonForScript(data),
|
|
1423
|
+
html,
|
|
1424
|
+
trustedHtml
|
|
1400
1425
|
};
|
|
1401
1426
|
}
|
|
1402
1427
|
|
|
@@ -1474,12 +1499,12 @@ function buildShell(content, config) {
|
|
|
1474
1499
|
sizing
|
|
1475
1500
|
});
|
|
1476
1501
|
if (!withShell) {
|
|
1477
|
-
const
|
|
1502
|
+
const html3 = `${dataScript}
|
|
1478
1503
|
${content}`;
|
|
1479
1504
|
return {
|
|
1480
|
-
html:
|
|
1481
|
-
hash: simpleHash(
|
|
1482
|
-
size: Buffer.byteLength(
|
|
1505
|
+
html: html3,
|
|
1506
|
+
hash: simpleHash(html3),
|
|
1507
|
+
size: Buffer.byteLength(html3, "utf-8")
|
|
1483
1508
|
};
|
|
1484
1509
|
}
|
|
1485
1510
|
if (customShell) {
|
|
@@ -1512,7 +1537,7 @@ ${content}`;
|
|
|
1512
1537
|
const bridgeScript = generateBridgeIIFE({ minify: true });
|
|
1513
1538
|
headParts.push(`<script>${bridgeScript}</script>`);
|
|
1514
1539
|
}
|
|
1515
|
-
const
|
|
1540
|
+
const html2 = `<!DOCTYPE html>
|
|
1516
1541
|
<html lang="en">
|
|
1517
1542
|
<head>
|
|
1518
1543
|
${headParts.map((p) => ` ${p}`).join("\n")}
|
|
@@ -1522,9 +1547,9 @@ ${content}
|
|
|
1522
1547
|
</body>
|
|
1523
1548
|
</html>`;
|
|
1524
1549
|
return {
|
|
1525
|
-
html,
|
|
1526
|
-
hash: simpleHash(
|
|
1527
|
-
size: Buffer.byteLength(
|
|
1550
|
+
html: html2,
|
|
1551
|
+
hash: simpleHash(html2),
|
|
1552
|
+
size: Buffer.byteLength(html2, "utf-8")
|
|
1528
1553
|
};
|
|
1529
1554
|
}
|
|
1530
1555
|
function buildCustomShell(content, customShell, ctx) {
|
|
@@ -1557,7 +1582,7 @@ ${sizingStyle}` : dataScript;
|
|
|
1557
1582
|
const bridgeScript = generateBridgeIIFE({ minify: true });
|
|
1558
1583
|
bridgeHtml = `<script>${bridgeScript}</script>`;
|
|
1559
1584
|
}
|
|
1560
|
-
const
|
|
1585
|
+
const html2 = applyShellTemplate(template, {
|
|
1561
1586
|
csp: cspTag,
|
|
1562
1587
|
data: dataWithSizing,
|
|
1563
1588
|
bridge: bridgeHtml,
|
|
@@ -1565,9 +1590,9 @@ ${sizingStyle}` : dataScript;
|
|
|
1565
1590
|
title: ctx.title ? escapeHtmlForTag(ctx.title) : ""
|
|
1566
1591
|
});
|
|
1567
1592
|
return {
|
|
1568
|
-
html,
|
|
1569
|
-
hash: simpleHash(
|
|
1570
|
-
size: Buffer.byteLength(
|
|
1593
|
+
html: html2,
|
|
1594
|
+
hash: simpleHash(html2),
|
|
1595
|
+
size: Buffer.byteLength(html2, "utf-8")
|
|
1571
1596
|
};
|
|
1572
1597
|
}
|
|
1573
1598
|
function simpleHash(str) {
|
|
@@ -1708,11 +1733,14 @@ export {
|
|
|
1708
1733
|
clearShellTemplateCache,
|
|
1709
1734
|
createTemplateHelpers,
|
|
1710
1735
|
hasSizing,
|
|
1736
|
+
html,
|
|
1711
1737
|
isInlineShellSource,
|
|
1712
1738
|
isNpmShellSource,
|
|
1739
|
+
isTrustedHtml,
|
|
1713
1740
|
isUrlShellSource,
|
|
1714
1741
|
resolveShellTemplate,
|
|
1715
1742
|
sanitizeCSPDomains,
|
|
1743
|
+
trustedHtml,
|
|
1716
1744
|
validateCSPDomain,
|
|
1717
1745
|
validateShellTemplate
|
|
1718
1746
|
};
|
package/index.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export * from './utils';
|
|
|
17
17
|
export { generateBridgeIIFE, generatePlatformBundle, UNIVERSAL_BRIDGE_SCRIPT, BRIDGE_SCRIPT_TAGS, type IIFEGeneratorOptions, } from './bridge-runtime';
|
|
18
18
|
export { type TypeFetchResult, type TypeFetchError, type TypeFetchErrorCode, type TypeFetchBatchRequest, type TypeFetchBatchResult, type TypeCacheEntry, type TypeCacheStats, type DtsImport, type DtsParseResult, type TypeFetcherOptions, type PackageResolution, DEFAULT_TYPE_FETCHER_OPTIONS, TYPE_CACHE_PREFIX, DEFAULT_TYPE_CACHE_TTL, type TypeCacheAdapter, type TypeCacheOptions, DEFAULT_CACHE_OPTIONS as DEFAULT_TYPE_CACHE_OPTIONS, MemoryTypeCache, globalTypeCache, parseDtsImports, isRelativeImport, getPackageFromSpecifier, getSubpathFromSpecifier, parseImportStatement, combineDtsContents, TypeFetcher, createTypeFetcher, } from './typings';
|
|
19
19
|
export * from './resolver';
|
|
20
|
-
export { type ShellConfig, type ShellResult, type CSPConfig, type ShellMountDescriptor, type ShellDataInjectionDescriptor, buildShell, DEFAULT_CDN_DOMAINS, DEFAULT_CSP_DIRECTIVES, RESTRICTIVE_CSP_DIRECTIVES, buildCSPDirectives, buildCSPMetaTag, validateCSPDomain, sanitizeCSPDomains, buildDataInjectionScript, buildCustomDataInjectionScript, createTemplateHelpers, type ShellPlaceholderName, type InlineShellSource, type UrlShellSource, type NpmShellSource, type CustomShellSource, type ShellTemplateValidation, type ResolvedShellTemplate, type ShellPlaceholderValues, type ResolveShellOptions, SHELL_PLACEHOLDER_NAMES, SHELL_PLACEHOLDERS, REQUIRED_PLACEHOLDERS, OPTIONAL_PLACEHOLDERS, isInlineShellSource, isUrlShellSource, isNpmShellSource, validateShellTemplate, applyShellTemplate, resolveShellTemplate, clearShellTemplateCache, } from './shell';
|
|
20
|
+
export { type ShellConfig, type ShellResult, type CSPConfig, type ShellMountDescriptor, type ShellDataInjectionDescriptor, buildShell, DEFAULT_CDN_DOMAINS, DEFAULT_CSP_DIRECTIVES, RESTRICTIVE_CSP_DIRECTIVES, buildCSPDirectives, buildCSPMetaTag, validateCSPDomain, sanitizeCSPDomains, buildDataInjectionScript, buildCustomDataInjectionScript, createTemplateHelpers, html, trustedHtml, isTrustedHtml, type TrustedHtml, type ShellPlaceholderName, type InlineShellSource, type UrlShellSource, type NpmShellSource, type CustomShellSource, type ShellTemplateValidation, type ResolvedShellTemplate, type ShellPlaceholderValues, type ResolveShellOptions, SHELL_PLACEHOLDER_NAMES, SHELL_PLACEHOLDERS, REQUIRED_PLACEHOLDERS, OPTIONAL_PLACEHOLDERS, isInlineShellSource, isUrlShellSource, isNpmShellSource, validateShellTemplate, applyShellTemplate, resolveShellTemplate, clearShellTemplateCache, } from './shell';
|
|
21
21
|
export * from './component';
|
|
22
22
|
export * from './adapters';
|
|
23
23
|
//# sourceMappingURL=index.d.ts.map
|
package/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,cAAc,SAAS,CAAC;AAKxB,cAAc,SAAS,CAAC;AAKxB,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,kBAAkB,EAClB,KAAK,oBAAoB,GAC1B,MAAM,kBAAkB,CAAC;AAK1B,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,4BAA4B,EAC5B,iBAAiB,EACjB,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,qBAAqB,IAAI,0BAA0B,EACnD,eAAe,EACf,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,EAClB,WAAW,EACX,iBAAiB,GAClB,MAAM,WAAW,CAAC;AAKnB,cAAc,YAAY,CAAC;AAM3B,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EACjC,UAAU,EACV,mBAAmB,EACnB,sBAAsB,EACtB,0BAA0B,EAC1B,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,8BAA8B,EAC9B,qBAAqB,EAErB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,kBAAkB,EAClB,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,SAAS,CAAC;AAKjB,cAAc,aAAa,CAAC;AAK5B,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,cAAc,SAAS,CAAC;AAKxB,cAAc,SAAS,CAAC;AAKxB,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,kBAAkB,EAClB,KAAK,oBAAoB,GAC1B,MAAM,kBAAkB,CAAC;AAK1B,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,4BAA4B,EAC5B,iBAAiB,EACjB,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,qBAAqB,IAAI,0BAA0B,EACnD,eAAe,EACf,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,EAClB,WAAW,EACX,iBAAiB,GAClB,MAAM,WAAW,CAAC;AAKnB,cAAc,YAAY,CAAC;AAM3B,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EACjC,UAAU,EACV,mBAAmB,EACnB,sBAAsB,EACtB,0BAA0B,EAC1B,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,8BAA8B,EAC9B,qBAAqB,EAErB,IAAI,EACJ,WAAW,EACX,aAAa,EACb,KAAK,WAAW,EAEhB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,kBAAkB,EAClB,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,SAAS,CAAC;AAKjB,cAAc,aAAa,CAAC;AAK5B,cAAc,YAAY,CAAC"}
|
package/index.js
CHANGED
|
@@ -84,6 +84,7 @@ __export(index_exports, {
|
|
|
84
84
|
getRegisteredPackages: () => getRegisteredPackages,
|
|
85
85
|
getSubpathFromSpecifier: () => getSubpathFromSpecifier,
|
|
86
86
|
globalTypeCache: () => globalTypeCache,
|
|
87
|
+
html: () => html,
|
|
87
88
|
isBundlingMode: () => isBundlingMode,
|
|
88
89
|
isDisplayMode: () => isDisplayMode,
|
|
89
90
|
isFileSource: () => isFileSource,
|
|
@@ -96,6 +97,7 @@ __export(index_exports, {
|
|
|
96
97
|
isPackageRegistered: () => isPackageRegistered,
|
|
97
98
|
isRelativeImport: () => isRelativeImport,
|
|
98
99
|
isResourceMode: () => isResourceMode,
|
|
100
|
+
isTrustedHtml: () => isTrustedHtml,
|
|
99
101
|
isUIRenderFailure: () => isUIRenderFailure,
|
|
100
102
|
isUIType: () => isUIType,
|
|
101
103
|
isUrlShellSource: () => isUrlShellSource,
|
|
@@ -115,6 +117,7 @@ __export(index_exports, {
|
|
|
115
117
|
safeStringify: () => safeStringify,
|
|
116
118
|
sanitizeCSPDomains: () => sanitizeCSPDomains,
|
|
117
119
|
transpileReactSource: () => transpileReactSource,
|
|
120
|
+
trustedHtml: () => trustedHtml,
|
|
118
121
|
validateCSPDomain: () => validateCSPDomain,
|
|
119
122
|
validateImportMap: () => validateImportMap,
|
|
120
123
|
validateShellTemplate: () => validateShellTemplate,
|
|
@@ -3034,6 +3037,29 @@ function validateShellTemplate(template) {
|
|
|
3034
3037
|
};
|
|
3035
3038
|
}
|
|
3036
3039
|
|
|
3040
|
+
// libs/uipack/src/shell/trusted-html.ts
|
|
3041
|
+
var TRUSTED_HTML = /* @__PURE__ */ Symbol.for("@frontmcp/uipack/trusted-html");
|
|
3042
|
+
function trustedHtml(markup) {
|
|
3043
|
+
const value = String(markup);
|
|
3044
|
+
return Object.freeze({ [TRUSTED_HTML]: value, toString: () => value });
|
|
3045
|
+
}
|
|
3046
|
+
function isTrustedHtml(value) {
|
|
3047
|
+
return typeof value === "object" && value !== null && typeof value[TRUSTED_HTML] === "string";
|
|
3048
|
+
}
|
|
3049
|
+
function interpolate(value) {
|
|
3050
|
+
if (isTrustedHtml(value)) return value[TRUSTED_HTML];
|
|
3051
|
+
if (Array.isArray(value)) return value.map(interpolate).join("");
|
|
3052
|
+
if (value === false) return "";
|
|
3053
|
+
return escapeHtml(value);
|
|
3054
|
+
}
|
|
3055
|
+
function html(strings, ...values) {
|
|
3056
|
+
let markup = strings[0];
|
|
3057
|
+
for (let index = 0; index < values.length; index++) {
|
|
3058
|
+
markup += interpolate(values[index]) + strings[index + 1];
|
|
3059
|
+
}
|
|
3060
|
+
return trustedHtml(markup);
|
|
3061
|
+
}
|
|
3062
|
+
|
|
3037
3063
|
// libs/uipack/src/shell/data-injector.ts
|
|
3038
3064
|
function hasSizing(sizing) {
|
|
3039
3065
|
if (!sizing) return false;
|
|
@@ -3087,7 +3113,9 @@ function createTemplateHelpers() {
|
|
|
3087
3113
|
uniqueId: (prefix = "mcp") => {
|
|
3088
3114
|
return `${prefix}-${++_uniqueIdCounter}`;
|
|
3089
3115
|
},
|
|
3090
|
-
jsonEmbed: (data) => safeJsonForScript(data)
|
|
3116
|
+
jsonEmbed: (data) => safeJsonForScript(data),
|
|
3117
|
+
html,
|
|
3118
|
+
trustedHtml
|
|
3091
3119
|
};
|
|
3092
3120
|
}
|
|
3093
3121
|
|
|
@@ -3165,12 +3193,12 @@ function buildShell(content, config) {
|
|
|
3165
3193
|
sizing
|
|
3166
3194
|
});
|
|
3167
3195
|
if (!withShell) {
|
|
3168
|
-
const
|
|
3196
|
+
const html3 = `${dataScript}
|
|
3169
3197
|
${content}`;
|
|
3170
3198
|
return {
|
|
3171
|
-
html:
|
|
3172
|
-
hash: simpleHash(
|
|
3173
|
-
size: Buffer.byteLength(
|
|
3199
|
+
html: html3,
|
|
3200
|
+
hash: simpleHash(html3),
|
|
3201
|
+
size: Buffer.byteLength(html3, "utf-8")
|
|
3174
3202
|
};
|
|
3175
3203
|
}
|
|
3176
3204
|
if (customShell) {
|
|
@@ -3203,7 +3231,7 @@ ${content}`;
|
|
|
3203
3231
|
const bridgeScript = generateBridgeIIFE({ minify: true });
|
|
3204
3232
|
headParts.push(`<script>${bridgeScript}</script>`);
|
|
3205
3233
|
}
|
|
3206
|
-
const
|
|
3234
|
+
const html2 = `<!DOCTYPE html>
|
|
3207
3235
|
<html lang="en">
|
|
3208
3236
|
<head>
|
|
3209
3237
|
${headParts.map((p) => ` ${p}`).join("\n")}
|
|
@@ -3213,9 +3241,9 @@ ${content}
|
|
|
3213
3241
|
</body>
|
|
3214
3242
|
</html>`;
|
|
3215
3243
|
return {
|
|
3216
|
-
html,
|
|
3217
|
-
hash: simpleHash(
|
|
3218
|
-
size: Buffer.byteLength(
|
|
3244
|
+
html: html2,
|
|
3245
|
+
hash: simpleHash(html2),
|
|
3246
|
+
size: Buffer.byteLength(html2, "utf-8")
|
|
3219
3247
|
};
|
|
3220
3248
|
}
|
|
3221
3249
|
function buildCustomShell(content, customShell, ctx) {
|
|
@@ -3248,7 +3276,7 @@ ${sizingStyle}` : dataScript;
|
|
|
3248
3276
|
const bridgeScript = generateBridgeIIFE({ minify: true });
|
|
3249
3277
|
bridgeHtml = `<script>${bridgeScript}</script>`;
|
|
3250
3278
|
}
|
|
3251
|
-
const
|
|
3279
|
+
const html2 = applyShellTemplate(template, {
|
|
3252
3280
|
csp: cspTag,
|
|
3253
3281
|
data: dataWithSizing,
|
|
3254
3282
|
bridge: bridgeHtml,
|
|
@@ -3256,9 +3284,9 @@ ${sizingStyle}` : dataScript;
|
|
|
3256
3284
|
title: ctx.title ? escapeHtmlForTag(ctx.title) : ""
|
|
3257
3285
|
});
|
|
3258
3286
|
return {
|
|
3259
|
-
html,
|
|
3260
|
-
hash: simpleHash(
|
|
3261
|
-
size: Buffer.byteLength(
|
|
3287
|
+
html: html2,
|
|
3288
|
+
hash: simpleHash(html2),
|
|
3289
|
+
size: Buffer.byteLength(html2, "utf-8")
|
|
3262
3290
|
};
|
|
3263
3291
|
}
|
|
3264
3292
|
function simpleHash(str) {
|
|
@@ -3665,10 +3693,10 @@ function resolveFileSource(source, options = {}) {
|
|
|
3665
3693
|
};
|
|
3666
3694
|
}
|
|
3667
3695
|
function resolveFunctionSource(source, input, output) {
|
|
3668
|
-
const
|
|
3696
|
+
const html2 = source(input, output);
|
|
3669
3697
|
return {
|
|
3670
3698
|
mode: "inline",
|
|
3671
|
-
html,
|
|
3699
|
+
html: html2,
|
|
3672
3700
|
exportName: "default",
|
|
3673
3701
|
meta: { mcpAware: false, renderer: "html" },
|
|
3674
3702
|
peerDependencies: []
|
|
@@ -4114,11 +4142,29 @@ function buildCspConfig(resolver) {
|
|
|
4114
4142
|
}
|
|
4115
4143
|
return { resourceDomains: cspResourceDomains, connectDomains: cspConnectDomains };
|
|
4116
4144
|
}
|
|
4117
|
-
|
|
4145
|
+
var STRING_RESULT_DOCS = "https://docs.agentfront.dev/frontmcp/guides/building-tool-ui#trusted-markup";
|
|
4146
|
+
var noticedStringResultTools = /* @__PURE__ */ new Set();
|
|
4147
|
+
function noticeStringResult(toolName, logger) {
|
|
4148
|
+
if (noticedStringResultTools.has(toolName)) return;
|
|
4149
|
+
noticedStringResultTools.add(toolName);
|
|
4150
|
+
logger.warn(
|
|
4151
|
+
`[frontmcp] The UI template of tool "${toolName}" returned a plain string containing markup, which is rendered as HTML. FrontMCP 1.9 will HTML-escape plain string results by default. Build the markup with ctx.helpers.html\`\u2026\` (interpolated values are escaped) or wrap safe markup with ctx.helpers.trustedHtml(), then set ui.escapeStringResults: true (or escapeStringResults: false to keep the current behaviour without this notice). See ${STRING_RESULT_DOCS}`
|
|
4152
|
+
);
|
|
4153
|
+
}
|
|
4154
|
+
function renderUnwrappedResult(rawResult, options) {
|
|
4155
|
+
if (isTrustedHtml(rawResult)) {
|
|
4156
|
+
return String(rawResult);
|
|
4157
|
+
}
|
|
4118
4158
|
if (typeof rawResult !== "string") {
|
|
4119
4159
|
return `<pre>${escapeHtml(JSON.stringify(rawResult, null, 2))}</pre>`;
|
|
4120
4160
|
}
|
|
4121
|
-
|
|
4161
|
+
if (detectContentType(rawResult) !== "html" || options.escapeStringResults === true) {
|
|
4162
|
+
return escapeHtml(rawResult);
|
|
4163
|
+
}
|
|
4164
|
+
if (options.escapeStringResults === void 0) {
|
|
4165
|
+
noticeStringResult(options.toolName, options.logger ?? console);
|
|
4166
|
+
}
|
|
4167
|
+
return rawResult;
|
|
4122
4168
|
}
|
|
4123
4169
|
function renderToolTemplate(options) {
|
|
4124
4170
|
const { toolName, input, output, template, resolver, platformType, sizing } = options;
|
|
@@ -4132,7 +4178,7 @@ function renderToolTemplate(options) {
|
|
|
4132
4178
|
resolver,
|
|
4133
4179
|
sizing
|
|
4134
4180
|
};
|
|
4135
|
-
let
|
|
4181
|
+
let html2;
|
|
4136
4182
|
let hash = "";
|
|
4137
4183
|
let size = 0;
|
|
4138
4184
|
if (typeof template === "object" && template !== null && "file" in template) {
|
|
@@ -4141,43 +4187,43 @@ function renderToolTemplate(options) {
|
|
|
4141
4187
|
{ source: template, inlineReact: resourceMode === "inline" },
|
|
4142
4188
|
{ ...shellConfig, csp: cspConfig }
|
|
4143
4189
|
);
|
|
4144
|
-
|
|
4190
|
+
html2 = result.html;
|
|
4145
4191
|
hash = result.hash;
|
|
4146
4192
|
size = result.size;
|
|
4147
4193
|
} else if (typeof template === "function") {
|
|
4148
4194
|
if (uiType === "react") {
|
|
4149
4195
|
const shellResult = buildShell('<div id="root"></div>', shellConfig);
|
|
4150
|
-
|
|
4196
|
+
html2 = shellResult.html;
|
|
4151
4197
|
hash = shellResult.hash;
|
|
4152
4198
|
size = shellResult.size;
|
|
4153
4199
|
} else {
|
|
4154
4200
|
const helpers = createTemplateHelpers();
|
|
4155
4201
|
const ctx = { input, output, helpers };
|
|
4156
4202
|
const rawResult = template(ctx);
|
|
4157
|
-
const wrapped = wrapDetectedContent(rawResult);
|
|
4203
|
+
const wrapped = isTrustedHtml(rawResult) ? void 0 : wrapDetectedContent(rawResult);
|
|
4158
4204
|
if (wrapped) {
|
|
4159
|
-
|
|
4205
|
+
html2 = wrapped;
|
|
4160
4206
|
} else {
|
|
4161
|
-
const shellResult = buildShell(renderUnwrappedResult(rawResult), shellConfig);
|
|
4162
|
-
|
|
4207
|
+
const shellResult = buildShell(renderUnwrappedResult(rawResult, options), shellConfig);
|
|
4208
|
+
html2 = shellResult.html;
|
|
4163
4209
|
hash = shellResult.hash;
|
|
4164
4210
|
size = shellResult.size;
|
|
4165
4211
|
}
|
|
4166
4212
|
}
|
|
4167
4213
|
} else if (typeof template === "string") {
|
|
4168
4214
|
const shellResult = buildShell(template, shellConfig);
|
|
4169
|
-
|
|
4215
|
+
html2 = shellResult.html;
|
|
4170
4216
|
hash = shellResult.hash;
|
|
4171
4217
|
size = shellResult.size;
|
|
4172
4218
|
} else {
|
|
4173
4219
|
const shellResult = buildShell('<div id="root"></div>', shellConfig);
|
|
4174
|
-
|
|
4220
|
+
html2 = shellResult.html;
|
|
4175
4221
|
hash = shellResult.hash;
|
|
4176
4222
|
size = shellResult.size;
|
|
4177
4223
|
}
|
|
4178
4224
|
const htmlKey = "ui/html";
|
|
4179
4225
|
const meta = {
|
|
4180
|
-
[htmlKey]:
|
|
4226
|
+
[htmlKey]: html2,
|
|
4181
4227
|
"ui/type": uiType,
|
|
4182
4228
|
"ui/mimeType": MCP_APPS_MIME_TYPE
|
|
4183
4229
|
};
|
|
@@ -4188,10 +4234,10 @@ function renderToolTemplate(options) {
|
|
|
4188
4234
|
if (sizing.aspectRatio !== void 0) meta["ui/aspectRatio"] = sizing.aspectRatio;
|
|
4189
4235
|
}
|
|
4190
4236
|
return {
|
|
4191
|
-
html,
|
|
4237
|
+
html: html2,
|
|
4192
4238
|
uiType,
|
|
4193
4239
|
hash,
|
|
4194
|
-
size: size || Buffer.byteLength(
|
|
4240
|
+
size: size || Buffer.byteLength(html2, "utf8"),
|
|
4195
4241
|
meta
|
|
4196
4242
|
};
|
|
4197
4243
|
}
|
|
@@ -4335,6 +4381,7 @@ function buildCDNInfoForUIType(uiType) {
|
|
|
4335
4381
|
getRegisteredPackages,
|
|
4336
4382
|
getSubpathFromSpecifier,
|
|
4337
4383
|
globalTypeCache,
|
|
4384
|
+
html,
|
|
4338
4385
|
isBundlingMode,
|
|
4339
4386
|
isDisplayMode,
|
|
4340
4387
|
isFileSource,
|
|
@@ -4347,6 +4394,7 @@ function buildCDNInfoForUIType(uiType) {
|
|
|
4347
4394
|
isPackageRegistered,
|
|
4348
4395
|
isRelativeImport,
|
|
4349
4396
|
isResourceMode,
|
|
4397
|
+
isTrustedHtml,
|
|
4350
4398
|
isUIRenderFailure,
|
|
4351
4399
|
isUIType,
|
|
4352
4400
|
isUrlShellSource,
|
|
@@ -4366,6 +4414,7 @@ function buildCDNInfoForUIType(uiType) {
|
|
|
4366
4414
|
safeStringify,
|
|
4367
4415
|
sanitizeCSPDomains,
|
|
4368
4416
|
transpileReactSource,
|
|
4417
|
+
trustedHtml,
|
|
4369
4418
|
validateCSPDomain,
|
|
4370
4419
|
validateImportMap,
|
|
4371
4420
|
validateShellTemplate,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontmcp/uipack",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.3",
|
|
4
4
|
"description": "FrontMCP UIpack - HTML shell builder, pluggable import resolver, and NPM component loader for MCP UI (React-free core)",
|
|
5
5
|
"author": "AgentFront <info@agentfront.dev>",
|
|
6
6
|
"homepage": "https://docs.agentfront.dev",
|
|
@@ -61,6 +61,6 @@
|
|
|
61
61
|
"typescript": "^5.9.3"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
|
-
"@frontmcp/lazy-zod": "1.8.
|
|
64
|
+
"@frontmcp/lazy-zod": "1.8.3"
|
|
65
65
|
}
|
|
66
66
|
}
|