@frontmcp/uipack 1.8.4 → 1.8.6
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/adapters/index.js +146 -15
- package/bridge-runtime/iife-generator.d.ts.map +1 -1
- package/bridge-runtime/index.js +92 -11
- package/component/index.js +146 -15
- package/component/loader.d.ts.map +1 -1
- package/component/transpiler.d.ts.map +1 -1
- package/esm/adapters/index.mjs +146 -15
- package/esm/bridge-runtime/index.mjs +92 -11
- package/esm/component/index.mjs +146 -15
- package/esm/index.mjs +146 -15
- package/esm/package.json +8 -2
- package/esm/shell/index.mjs +92 -11
- package/index.js +146 -15
- package/package.json +8 -2
- package/shell/index.js +92 -11
- package/types/ui-config.d.ts +4 -2
- package/types/ui-config.d.ts.map +1 -1
package/index.js
CHANGED
|
@@ -358,6 +358,23 @@ function __applySizingCss(sizing) {
|
|
|
358
358
|
}
|
|
359
359
|
}
|
|
360
360
|
|
|
361
|
+
function __measureHeight() {
|
|
362
|
+
// <html> at fit-content includes body margins and collapsed child margins;
|
|
363
|
+
// content overflowing a fixed-height body is added; a px max-height clamps.
|
|
364
|
+
var de = document.documentElement;
|
|
365
|
+
var body = document.body;
|
|
366
|
+
if (!de || !body) return 0;
|
|
367
|
+
var prev = de.style.height;
|
|
368
|
+
de.style.height = 'fit-content';
|
|
369
|
+
var dr = de.getBoundingClientRect();
|
|
370
|
+
var br = body.getBoundingClientRect();
|
|
371
|
+
var h = Math.max(dr.height, br.top + body.scrollHeight + Math.max(0, dr.bottom - br.bottom) - dr.top);
|
|
372
|
+
de.style.height = prev;
|
|
373
|
+
var maxHeight = getComputedStyle(de).maxHeight;
|
|
374
|
+
var mx = maxHeight && maxHeight.slice(-2) === 'px' ? parseFloat(maxHeight) : NaN;
|
|
375
|
+
return Math.ceil(isNaN(mx) ? h : Math.min(h, mx));
|
|
376
|
+
}
|
|
377
|
+
|
|
361
378
|
function __initAutoResize() {
|
|
362
379
|
if (typeof window === 'undefined') return;
|
|
363
380
|
// Idempotent: a re-injected IIFE must not stack observers.
|
|
@@ -380,23 +397,30 @@ function __initAutoResize() {
|
|
|
380
397
|
if (typeof ResizeObserver === 'undefined') return;
|
|
381
398
|
|
|
382
399
|
function startObserving() {
|
|
383
|
-
|
|
384
|
-
|
|
400
|
+
if (!document.body) return;
|
|
401
|
+
var targets = [document.documentElement, document.body];
|
|
402
|
+
var root = document.getElementById('root');
|
|
403
|
+
if (root) targets.push(root);
|
|
385
404
|
|
|
386
405
|
var rafId = null;
|
|
387
406
|
var lastReported = -1;
|
|
388
407
|
function report() {
|
|
389
408
|
rafId = null;
|
|
390
409
|
try {
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
410
|
+
// Before the handshake an ext-apps host can't receive the report; the
|
|
411
|
+
// bridge:ready listener below sends it once the bridge is up.
|
|
412
|
+
if (window.FrontMcpBridge && window.FrontMcpBridge.initialized === false) return;
|
|
413
|
+
var height = __measureHeight();
|
|
414
|
+
var width = Math.ceil(document.documentElement.getBoundingClientRect().width);
|
|
394
415
|
if (height === lastReported || height <= 0) return;
|
|
395
416
|
lastReported = height;
|
|
396
417
|
var payload = { height: height, width: width };
|
|
397
418
|
if (sizing.aspectRatio != null) payload.aspectRatio = sizing.aspectRatio;
|
|
398
419
|
if (window.FrontMcpBridge && typeof window.FrontMcpBridge.setSize === 'function') {
|
|
399
|
-
window.FrontMcpBridge.setSize(payload).catch(function() {
|
|
420
|
+
window.FrontMcpBridge.setSize(payload).catch(function() {
|
|
421
|
+
// Forget a rejected report so the same height is sent again.
|
|
422
|
+
if (lastReported === height) lastReported = -1;
|
|
423
|
+
});
|
|
400
424
|
}
|
|
401
425
|
window.dispatchEvent(new CustomEvent('widget:resize', { detail: payload }));
|
|
402
426
|
} catch (e) {}
|
|
@@ -417,9 +441,17 @@ function __initAutoResize() {
|
|
|
417
441
|
window.__mcpResizeObserver.disconnect();
|
|
418
442
|
}
|
|
419
443
|
var ro = new ResizeObserver(function() { schedule(); });
|
|
420
|
-
ro.observe(
|
|
444
|
+
for (var i = 0; i < targets.length; i++) ro.observe(targets[i]);
|
|
421
445
|
window.__mcpResizeObserver = ro;
|
|
422
446
|
} catch (e) {}
|
|
447
|
+
// Report once the bridge is ready (the report scheduled below is skipped
|
|
448
|
+
// while the handshake is still pending).
|
|
449
|
+
var readySent = false;
|
|
450
|
+
window.addEventListener('bridge:ready', function() {
|
|
451
|
+
if (readySent) return;
|
|
452
|
+
readySent = true;
|
|
453
|
+
schedule();
|
|
454
|
+
});
|
|
423
455
|
// Report once on init so the host gets an initial measurement.
|
|
424
456
|
schedule();
|
|
425
457
|
}
|
|
@@ -467,6 +499,25 @@ function detectViewport() {
|
|
|
467
499
|
return undefined;
|
|
468
500
|
}
|
|
469
501
|
|
|
502
|
+
function __applyHostTheme(theme) {
|
|
503
|
+
// Follow a host-supplied theme: <meta name="color-scheme"> sets the frame's
|
|
504
|
+
// canvas and form controls (a widget's own :root color-scheme still wins),
|
|
505
|
+
// <html data-theme> is a styling hook. The OS fallback is never written.
|
|
506
|
+
if (theme !== 'light' && theme !== 'dark') return;
|
|
507
|
+
if (typeof document === 'undefined' || !document.documentElement) return;
|
|
508
|
+
try {
|
|
509
|
+
var meta = document.querySelector('meta[name="color-scheme"]');
|
|
510
|
+
var head = document.head || document.getElementsByTagName('head')[0];
|
|
511
|
+
if (!meta && head) {
|
|
512
|
+
meta = document.createElement('meta');
|
|
513
|
+
meta.setAttribute('name', 'color-scheme');
|
|
514
|
+
head.appendChild(meta);
|
|
515
|
+
}
|
|
516
|
+
if (meta) meta.setAttribute('content', theme);
|
|
517
|
+
document.documentElement.setAttribute('data-theme', theme);
|
|
518
|
+
} catch (e) {}
|
|
519
|
+
}
|
|
520
|
+
|
|
470
521
|
function readInjectedData() {
|
|
471
522
|
var data = { toolInput: {}, toolOutput: undefined, structuredContent: undefined };
|
|
472
523
|
if (typeof window !== 'undefined') {
|
|
@@ -573,6 +624,8 @@ var ExtAppsAdapter = {
|
|
|
573
624
|
pendingRequests: {},
|
|
574
625
|
requestId: 0,
|
|
575
626
|
hostCapabilities: {},
|
|
627
|
+
handshakeSettled: false,
|
|
628
|
+
pendingSize: null,
|
|
576
629
|
canHandle: function() {
|
|
577
630
|
if (typeof window === 'undefined') return false;
|
|
578
631
|
if (window.parent === window) return false;
|
|
@@ -738,6 +791,7 @@ var ExtAppsAdapter = {
|
|
|
738
791
|
var timeout = setTimeout(function() {
|
|
739
792
|
delete self.pendingRequests[id];
|
|
740
793
|
// Handshake timeout is non-fatal \u2014 notifications may still arrive
|
|
794
|
+
self.settleHandshake();
|
|
741
795
|
resolve();
|
|
742
796
|
}, 10000);
|
|
743
797
|
|
|
@@ -751,7 +805,9 @@ var ExtAppsAdapter = {
|
|
|
751
805
|
supportsDisplayModes: true
|
|
752
806
|
});
|
|
753
807
|
if (result.hostContext) {
|
|
754
|
-
|
|
808
|
+
// Notify (not a silent merge) so onContextChange listeners and the
|
|
809
|
+
// host theme see the handshake's context.
|
|
810
|
+
context.notifyContextChange(result.hostContext);
|
|
755
811
|
}
|
|
756
812
|
// Send ui/notifications/initialized to tell the host the view is ready.
|
|
757
813
|
// Per MCP Apps spec, the host waits for this before sending tool-result.
|
|
@@ -761,9 +817,10 @@ var ExtAppsAdapter = {
|
|
|
761
817
|
method: 'ui/notifications/initialized',
|
|
762
818
|
params: {}
|
|
763
819
|
}, targetOrigin);
|
|
820
|
+
self.settleHandshake();
|
|
764
821
|
resolve();
|
|
765
822
|
},
|
|
766
|
-
reject: function(err) { resolve(); }, // Non-fatal
|
|
823
|
+
reject: function(err) { self.settleHandshake(); resolve(); }, // Non-fatal
|
|
767
824
|
timeout: timeout
|
|
768
825
|
};
|
|
769
826
|
|
|
@@ -777,6 +834,18 @@ var ExtAppsAdapter = {
|
|
|
777
834
|
performHandshake: function(context) {
|
|
778
835
|
return this.sendHandshake(context);
|
|
779
836
|
},
|
|
837
|
+
settleHandshake: function() {
|
|
838
|
+
// Deliver the latest size requested while no host origin was trusted.
|
|
839
|
+
this.handshakeSettled = true;
|
|
840
|
+
var pending = this.pendingSize;
|
|
841
|
+
if (!pending) return;
|
|
842
|
+
this.pendingSize = null;
|
|
843
|
+
this.sendRequest('ui/setSize', pending.params).then(function(result) {
|
|
844
|
+
for (var i = 0; i < pending.waiters.length; i++) pending.waiters[i].resolve(result);
|
|
845
|
+
}, function(err) {
|
|
846
|
+
for (var i = 0; i < pending.waiters.length; i++) pending.waiters[i].reject(err);
|
|
847
|
+
});
|
|
848
|
+
},
|
|
780
849
|
callTool: function(context, name, args) {
|
|
781
850
|
if (!this.hostCapabilities.serverTools && !this.hostCapabilities.serverToolProxy) {
|
|
782
851
|
return Promise.reject(new Error('Server tool proxy not supported'));
|
|
@@ -800,11 +869,22 @@ var ExtAppsAdapter = {
|
|
|
800
869
|
setSize: function(context, size) {
|
|
801
870
|
// FrontMCP sizing channel \u2014 parallels ui/setDisplayMode. Reports the
|
|
802
871
|
// measured/desired widget dimensions to the host.
|
|
803
|
-
|
|
872
|
+
var params = {
|
|
804
873
|
height: size && size.height,
|
|
805
874
|
width: size && size.width,
|
|
806
875
|
aspectRatio: size && size.aspectRatio
|
|
807
|
-
}
|
|
876
|
+
};
|
|
877
|
+
if (!this.handshakeSettled && !this.trustedOrigin && this.trustedOrigins.length === 0) {
|
|
878
|
+
// No host origin yet: keep only the latest size and send it when the
|
|
879
|
+
// handshake settles; every caller's promise follows that one request.
|
|
880
|
+
var self = this;
|
|
881
|
+
if (!this.pendingSize) this.pendingSize = { params: params, waiters: [] };
|
|
882
|
+
this.pendingSize.params = params;
|
|
883
|
+
return new Promise(function(resolve, reject) {
|
|
884
|
+
self.pendingSize.waiters.push({ resolve: resolve, reject: reject });
|
|
885
|
+
});
|
|
886
|
+
}
|
|
887
|
+
return this.sendRequest('ui/setSize', params);
|
|
808
888
|
},
|
|
809
889
|
requestClose: function(context) {
|
|
810
890
|
return this.sendRequest('ui/close', {});
|
|
@@ -1050,6 +1130,7 @@ function FrontMcpBridge() {
|
|
|
1050
1130
|
toolResultListeners: [],
|
|
1051
1131
|
notifyContextChange: function(changes) {
|
|
1052
1132
|
Object.assign(this.hostContext, changes);
|
|
1133
|
+
if (changes && changes.theme) __applyHostTheme(changes.theme);
|
|
1053
1134
|
for (var i = 0; i < this.contextListeners.length; i++) {
|
|
1054
1135
|
try { this.contextListeners[i](changes); } catch(e) {}
|
|
1055
1136
|
}
|
|
@@ -3449,8 +3530,24 @@ function isFrontmcpUiResolvable(...candidatePaths) {
|
|
|
3449
3530
|
}
|
|
3450
3531
|
|
|
3451
3532
|
// libs/uipack/src/component/transpiler.ts
|
|
3533
|
+
function loadEsbuild(filename) {
|
|
3534
|
+
try {
|
|
3535
|
+
return require("esbuild");
|
|
3536
|
+
} catch (err) {
|
|
3537
|
+
if (!isMissingEsbuild(err)) throw err;
|
|
3538
|
+
const subject = filename ? `FileSource widget "${filename}"` : "A FileSource widget";
|
|
3539
|
+
throw new Error(
|
|
3540
|
+
`${subject} needs esbuild, which is not installed. @frontmcp/uipack loads esbuild on demand to bundle FileSource widgets (.tsx/.jsx) when the tool is called, so it must be installed where the server runs: \`npm install esbuild\` (in "dependencies", not "devDependencies"). Projects created with \`frontmcp create\` already get it through the \`frontmcp\` package.`,
|
|
3541
|
+
{ cause: err }
|
|
3542
|
+
);
|
|
3543
|
+
}
|
|
3544
|
+
}
|
|
3545
|
+
function isMissingEsbuild(err) {
|
|
3546
|
+
if (!(err instanceof Error)) return false;
|
|
3547
|
+
return err.code === "MODULE_NOT_FOUND" && /Cannot find module ['"]esbuild['"]/.test(err.message);
|
|
3548
|
+
}
|
|
3452
3549
|
function transpileReactSource(source, filename) {
|
|
3453
|
-
const esbuild =
|
|
3550
|
+
const esbuild = loadEsbuild(filename);
|
|
3454
3551
|
const loader = filename?.endsWith(".tsx") ? "tsx" : "jsx";
|
|
3455
3552
|
const result = esbuild.transformSync(source, {
|
|
3456
3553
|
loader,
|
|
@@ -3469,7 +3566,7 @@ function bundleFileSource(source, filename, resolveDir, componentName, options =
|
|
|
3469
3566
|
`FileSource widget "${filename}" requires the @frontmcp/ui package, which provides the React bridge mount that's injected at bundle time. Install it (e.g. \`npm install @frontmcp/ui\` or \`yarn add @frontmcp/ui\`) and try again.`
|
|
3470
3567
|
);
|
|
3471
3568
|
}
|
|
3472
|
-
const esbuild =
|
|
3569
|
+
const esbuild = loadEsbuild(filename);
|
|
3473
3570
|
const mountCode = `
|
|
3474
3571
|
// --- Auto-generated mount ---
|
|
3475
3572
|
import { createElement as __h } from 'react';
|
|
@@ -3566,7 +3663,8 @@ if (__root) {
|
|
|
3566
3663
|
} catch (err) {
|
|
3567
3664
|
const message = err instanceof Error ? err.message : String(err);
|
|
3568
3665
|
throw new Error(
|
|
3569
|
-
`Failed to bundle FileSource "${filename}": ${message}. If the error mentions @frontmcp/ui or @frontmcp/uipack, ensure both packages are installed in the consuming project
|
|
3666
|
+
`Failed to bundle FileSource "${filename}": ${message}. If the error mentions @frontmcp/ui or @frontmcp/uipack, ensure both packages are installed in the consuming project.`,
|
|
3667
|
+
{ cause: err }
|
|
3570
3668
|
);
|
|
3571
3669
|
}
|
|
3572
3670
|
}
|
|
@@ -3628,6 +3726,37 @@ function resolveImportSource(source) {
|
|
|
3628
3726
|
peerDependencies: []
|
|
3629
3727
|
};
|
|
3630
3728
|
}
|
|
3729
|
+
var BUILD_DIR_SEGMENTS = /* @__PURE__ */ new Set(["dist", "build", "out"]);
|
|
3730
|
+
function missingWidgetError(filePath, cause) {
|
|
3731
|
+
const sourceWidget = findSourceWidget(filePath);
|
|
3732
|
+
const error = new Error(
|
|
3733
|
+
`FileSource widget not found (ENOENT): no file at "${filePath}". The widget source is read from this path when the tool is called, so it has to exist where the compiled tool runs \u2014 a path built from \`__dirname\` or \`import.meta.url\` points into the build output once the tool is compiled. tsc does not copy \`*.widget.tsx\` / \`*.widget.jsx\` files into its output; \`frontmcp build\` does, and any other build needs a step that copies them next to the compiled tool.` + (sourceWidget ? ` The source widget exists at "${sourceWidget}" \u2014 copy it to "${filePath}", or build with \`frontmcp build\`.` : ""),
|
|
3734
|
+
{ cause }
|
|
3735
|
+
);
|
|
3736
|
+
error.code = "ENOENT";
|
|
3737
|
+
error.path = filePath;
|
|
3738
|
+
return error;
|
|
3739
|
+
}
|
|
3740
|
+
function findSourceWidget(filePath) {
|
|
3741
|
+
const path = require("path");
|
|
3742
|
+
const fs = require("fs");
|
|
3743
|
+
const parts = filePath.split(path.sep);
|
|
3744
|
+
for (let i = parts.length - 2; i >= 0; i--) {
|
|
3745
|
+
if (!BUILD_DIR_SEGMENTS.has(parts[i])) continue;
|
|
3746
|
+
const candidates = [[...parts.slice(0, i), "src", ...parts.slice(i + 1)]];
|
|
3747
|
+
if (parts.length - i > 2) candidates.push([...parts.slice(0, i), "src", ...parts.slice(i + 2)]);
|
|
3748
|
+
candidates.push([...parts.slice(0, i), ...parts.slice(i + 1)]);
|
|
3749
|
+
for (const candidate of candidates) {
|
|
3750
|
+
const candidatePath = candidate.join(path.sep);
|
|
3751
|
+
try {
|
|
3752
|
+
if (fs.existsSync(candidatePath)) return candidatePath;
|
|
3753
|
+
} catch {
|
|
3754
|
+
}
|
|
3755
|
+
}
|
|
3756
|
+
return void 0;
|
|
3757
|
+
}
|
|
3758
|
+
return void 0;
|
|
3759
|
+
}
|
|
3631
3760
|
function resolveFileSource(source, options = {}) {
|
|
3632
3761
|
const path = require("path");
|
|
3633
3762
|
const ext = path.extname(source.file).toLowerCase();
|
|
@@ -3642,9 +3771,11 @@ function resolveFileSource(source, options = {}) {
|
|
|
3642
3771
|
const isNotFound = err?.code === "ENOENT";
|
|
3643
3772
|
if (isNotFound && wasRelative) {
|
|
3644
3773
|
throw new Error(
|
|
3645
|
-
`FileSource widget "${source.file}" not found at "${filePath}". Relative paths are resolved against process.cwd() ("${process.cwd()}"), not the tool file's directory. To anchor the path to the tool file, pass an absolute path \u2014 e.g. \`{ file: fileURLToPath(new URL('./widget.tsx', import.meta.url)) }\` from \`node:url\` (see issue #444)
|
|
3774
|
+
`FileSource widget "${source.file}" not found at "${filePath}". Relative paths are resolved against process.cwd() ("${process.cwd()}"), not the tool file's directory. To anchor the path to the tool file, pass an absolute path \u2014 e.g. \`{ file: fileURLToPath(new URL('./widget.tsx', import.meta.url)) }\` from \`node:url\` (see issue #444).`,
|
|
3775
|
+
{ cause: err }
|
|
3646
3776
|
);
|
|
3647
3777
|
}
|
|
3778
|
+
if (isNotFound) throw missingWidgetError(filePath, err);
|
|
3648
3779
|
throw err;
|
|
3649
3780
|
}
|
|
3650
3781
|
const componentName = source.exportName || extractDefaultExportName(rawSource) || "Component";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontmcp/uipack",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.6",
|
|
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,12 @@
|
|
|
61
61
|
"typescript": "^5.9.3"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
|
-
"@frontmcp/lazy-zod": "1.8.
|
|
64
|
+
"@frontmcp/lazy-zod": "1.8.6",
|
|
65
|
+
"esbuild": ">=0.27.0 <1"
|
|
66
|
+
},
|
|
67
|
+
"peerDependenciesMeta": {
|
|
68
|
+
"esbuild": {
|
|
69
|
+
"optional": true
|
|
70
|
+
}
|
|
65
71
|
}
|
|
66
72
|
}
|
package/shell/index.js
CHANGED
|
@@ -157,6 +157,23 @@ function __applySizingCss(sizing) {
|
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
+
function __measureHeight() {
|
|
161
|
+
// <html> at fit-content includes body margins and collapsed child margins;
|
|
162
|
+
// content overflowing a fixed-height body is added; a px max-height clamps.
|
|
163
|
+
var de = document.documentElement;
|
|
164
|
+
var body = document.body;
|
|
165
|
+
if (!de || !body) return 0;
|
|
166
|
+
var prev = de.style.height;
|
|
167
|
+
de.style.height = 'fit-content';
|
|
168
|
+
var dr = de.getBoundingClientRect();
|
|
169
|
+
var br = body.getBoundingClientRect();
|
|
170
|
+
var h = Math.max(dr.height, br.top + body.scrollHeight + Math.max(0, dr.bottom - br.bottom) - dr.top);
|
|
171
|
+
de.style.height = prev;
|
|
172
|
+
var maxHeight = getComputedStyle(de).maxHeight;
|
|
173
|
+
var mx = maxHeight && maxHeight.slice(-2) === 'px' ? parseFloat(maxHeight) : NaN;
|
|
174
|
+
return Math.ceil(isNaN(mx) ? h : Math.min(h, mx));
|
|
175
|
+
}
|
|
176
|
+
|
|
160
177
|
function __initAutoResize() {
|
|
161
178
|
if (typeof window === 'undefined') return;
|
|
162
179
|
// Idempotent: a re-injected IIFE must not stack observers.
|
|
@@ -179,23 +196,30 @@ function __initAutoResize() {
|
|
|
179
196
|
if (typeof ResizeObserver === 'undefined') return;
|
|
180
197
|
|
|
181
198
|
function startObserving() {
|
|
182
|
-
|
|
183
|
-
|
|
199
|
+
if (!document.body) return;
|
|
200
|
+
var targets = [document.documentElement, document.body];
|
|
201
|
+
var root = document.getElementById('root');
|
|
202
|
+
if (root) targets.push(root);
|
|
184
203
|
|
|
185
204
|
var rafId = null;
|
|
186
205
|
var lastReported = -1;
|
|
187
206
|
function report() {
|
|
188
207
|
rafId = null;
|
|
189
208
|
try {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
209
|
+
// Before the handshake an ext-apps host can't receive the report; the
|
|
210
|
+
// bridge:ready listener below sends it once the bridge is up.
|
|
211
|
+
if (window.FrontMcpBridge && window.FrontMcpBridge.initialized === false) return;
|
|
212
|
+
var height = __measureHeight();
|
|
213
|
+
var width = Math.ceil(document.documentElement.getBoundingClientRect().width);
|
|
193
214
|
if (height === lastReported || height <= 0) return;
|
|
194
215
|
lastReported = height;
|
|
195
216
|
var payload = { height: height, width: width };
|
|
196
217
|
if (sizing.aspectRatio != null) payload.aspectRatio = sizing.aspectRatio;
|
|
197
218
|
if (window.FrontMcpBridge && typeof window.FrontMcpBridge.setSize === 'function') {
|
|
198
|
-
window.FrontMcpBridge.setSize(payload).catch(function() {
|
|
219
|
+
window.FrontMcpBridge.setSize(payload).catch(function() {
|
|
220
|
+
// Forget a rejected report so the same height is sent again.
|
|
221
|
+
if (lastReported === height) lastReported = -1;
|
|
222
|
+
});
|
|
199
223
|
}
|
|
200
224
|
window.dispatchEvent(new CustomEvent('widget:resize', { detail: payload }));
|
|
201
225
|
} catch (e) {}
|
|
@@ -216,9 +240,17 @@ function __initAutoResize() {
|
|
|
216
240
|
window.__mcpResizeObserver.disconnect();
|
|
217
241
|
}
|
|
218
242
|
var ro = new ResizeObserver(function() { schedule(); });
|
|
219
|
-
ro.observe(
|
|
243
|
+
for (var i = 0; i < targets.length; i++) ro.observe(targets[i]);
|
|
220
244
|
window.__mcpResizeObserver = ro;
|
|
221
245
|
} catch (e) {}
|
|
246
|
+
// Report once the bridge is ready (the report scheduled below is skipped
|
|
247
|
+
// while the handshake is still pending).
|
|
248
|
+
var readySent = false;
|
|
249
|
+
window.addEventListener('bridge:ready', function() {
|
|
250
|
+
if (readySent) return;
|
|
251
|
+
readySent = true;
|
|
252
|
+
schedule();
|
|
253
|
+
});
|
|
222
254
|
// Report once on init so the host gets an initial measurement.
|
|
223
255
|
schedule();
|
|
224
256
|
}
|
|
@@ -266,6 +298,25 @@ function detectViewport() {
|
|
|
266
298
|
return undefined;
|
|
267
299
|
}
|
|
268
300
|
|
|
301
|
+
function __applyHostTheme(theme) {
|
|
302
|
+
// Follow a host-supplied theme: <meta name="color-scheme"> sets the frame's
|
|
303
|
+
// canvas and form controls (a widget's own :root color-scheme still wins),
|
|
304
|
+
// <html data-theme> is a styling hook. The OS fallback is never written.
|
|
305
|
+
if (theme !== 'light' && theme !== 'dark') return;
|
|
306
|
+
if (typeof document === 'undefined' || !document.documentElement) return;
|
|
307
|
+
try {
|
|
308
|
+
var meta = document.querySelector('meta[name="color-scheme"]');
|
|
309
|
+
var head = document.head || document.getElementsByTagName('head')[0];
|
|
310
|
+
if (!meta && head) {
|
|
311
|
+
meta = document.createElement('meta');
|
|
312
|
+
meta.setAttribute('name', 'color-scheme');
|
|
313
|
+
head.appendChild(meta);
|
|
314
|
+
}
|
|
315
|
+
if (meta) meta.setAttribute('content', theme);
|
|
316
|
+
document.documentElement.setAttribute('data-theme', theme);
|
|
317
|
+
} catch (e) {}
|
|
318
|
+
}
|
|
319
|
+
|
|
269
320
|
function readInjectedData() {
|
|
270
321
|
var data = { toolInput: {}, toolOutput: undefined, structuredContent: undefined };
|
|
271
322
|
if (typeof window !== 'undefined') {
|
|
@@ -372,6 +423,8 @@ var ExtAppsAdapter = {
|
|
|
372
423
|
pendingRequests: {},
|
|
373
424
|
requestId: 0,
|
|
374
425
|
hostCapabilities: {},
|
|
426
|
+
handshakeSettled: false,
|
|
427
|
+
pendingSize: null,
|
|
375
428
|
canHandle: function() {
|
|
376
429
|
if (typeof window === 'undefined') return false;
|
|
377
430
|
if (window.parent === window) return false;
|
|
@@ -537,6 +590,7 @@ var ExtAppsAdapter = {
|
|
|
537
590
|
var timeout = setTimeout(function() {
|
|
538
591
|
delete self.pendingRequests[id];
|
|
539
592
|
// Handshake timeout is non-fatal \u2014 notifications may still arrive
|
|
593
|
+
self.settleHandshake();
|
|
540
594
|
resolve();
|
|
541
595
|
}, 10000);
|
|
542
596
|
|
|
@@ -550,7 +604,9 @@ var ExtAppsAdapter = {
|
|
|
550
604
|
supportsDisplayModes: true
|
|
551
605
|
});
|
|
552
606
|
if (result.hostContext) {
|
|
553
|
-
|
|
607
|
+
// Notify (not a silent merge) so onContextChange listeners and the
|
|
608
|
+
// host theme see the handshake's context.
|
|
609
|
+
context.notifyContextChange(result.hostContext);
|
|
554
610
|
}
|
|
555
611
|
// Send ui/notifications/initialized to tell the host the view is ready.
|
|
556
612
|
// Per MCP Apps spec, the host waits for this before sending tool-result.
|
|
@@ -560,9 +616,10 @@ var ExtAppsAdapter = {
|
|
|
560
616
|
method: 'ui/notifications/initialized',
|
|
561
617
|
params: {}
|
|
562
618
|
}, targetOrigin);
|
|
619
|
+
self.settleHandshake();
|
|
563
620
|
resolve();
|
|
564
621
|
},
|
|
565
|
-
reject: function(err) { resolve(); }, // Non-fatal
|
|
622
|
+
reject: function(err) { self.settleHandshake(); resolve(); }, // Non-fatal
|
|
566
623
|
timeout: timeout
|
|
567
624
|
};
|
|
568
625
|
|
|
@@ -576,6 +633,18 @@ var ExtAppsAdapter = {
|
|
|
576
633
|
performHandshake: function(context) {
|
|
577
634
|
return this.sendHandshake(context);
|
|
578
635
|
},
|
|
636
|
+
settleHandshake: function() {
|
|
637
|
+
// Deliver the latest size requested while no host origin was trusted.
|
|
638
|
+
this.handshakeSettled = true;
|
|
639
|
+
var pending = this.pendingSize;
|
|
640
|
+
if (!pending) return;
|
|
641
|
+
this.pendingSize = null;
|
|
642
|
+
this.sendRequest('ui/setSize', pending.params).then(function(result) {
|
|
643
|
+
for (var i = 0; i < pending.waiters.length; i++) pending.waiters[i].resolve(result);
|
|
644
|
+
}, function(err) {
|
|
645
|
+
for (var i = 0; i < pending.waiters.length; i++) pending.waiters[i].reject(err);
|
|
646
|
+
});
|
|
647
|
+
},
|
|
579
648
|
callTool: function(context, name, args) {
|
|
580
649
|
if (!this.hostCapabilities.serverTools && !this.hostCapabilities.serverToolProxy) {
|
|
581
650
|
return Promise.reject(new Error('Server tool proxy not supported'));
|
|
@@ -599,11 +668,22 @@ var ExtAppsAdapter = {
|
|
|
599
668
|
setSize: function(context, size) {
|
|
600
669
|
// FrontMCP sizing channel \u2014 parallels ui/setDisplayMode. Reports the
|
|
601
670
|
// measured/desired widget dimensions to the host.
|
|
602
|
-
|
|
671
|
+
var params = {
|
|
603
672
|
height: size && size.height,
|
|
604
673
|
width: size && size.width,
|
|
605
674
|
aspectRatio: size && size.aspectRatio
|
|
606
|
-
}
|
|
675
|
+
};
|
|
676
|
+
if (!this.handshakeSettled && !this.trustedOrigin && this.trustedOrigins.length === 0) {
|
|
677
|
+
// No host origin yet: keep only the latest size and send it when the
|
|
678
|
+
// handshake settles; every caller's promise follows that one request.
|
|
679
|
+
var self = this;
|
|
680
|
+
if (!this.pendingSize) this.pendingSize = { params: params, waiters: [] };
|
|
681
|
+
this.pendingSize.params = params;
|
|
682
|
+
return new Promise(function(resolve, reject) {
|
|
683
|
+
self.pendingSize.waiters.push({ resolve: resolve, reject: reject });
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
return this.sendRequest('ui/setSize', params);
|
|
607
687
|
},
|
|
608
688
|
requestClose: function(context) {
|
|
609
689
|
return this.sendRequest('ui/close', {});
|
|
@@ -849,6 +929,7 @@ function FrontMcpBridge() {
|
|
|
849
929
|
toolResultListeners: [],
|
|
850
930
|
notifyContextChange: function(changes) {
|
|
851
931
|
Object.assign(this.hostContext, changes);
|
|
932
|
+
if (changes && changes.theme) __applyHostTheme(changes.theme);
|
|
852
933
|
for (var i = 0; i < this.contextListeners.length; i++) {
|
|
853
934
|
try { this.contextListeners[i](changes); } catch(e) {}
|
|
854
935
|
}
|
package/types/ui-config.d.ts
CHANGED
|
@@ -404,8 +404,10 @@ export interface UITemplateConfig<In = unknown, Out = unknown> {
|
|
|
404
404
|
*/
|
|
405
405
|
aspectRatio?: string | number;
|
|
406
406
|
/**
|
|
407
|
-
* Whether the widget should auto-report its
|
|
408
|
-
*
|
|
407
|
+
* Whether the widget should auto-report its height to the host as it changes
|
|
408
|
+
* (via a debounced `ResizeObserver` on `<html>`, `<body>` and `#root`). The
|
|
409
|
+
* whole document is measured, margins included; the first report is sent once
|
|
410
|
+
* the host handshake completes.
|
|
409
411
|
*
|
|
410
412
|
* Only takes effect when the widget configures sizing — i.e. at least one
|
|
411
413
|
* sizing field (`preferredHeight` / `minHeight` / `maxHeight` / `aspectRatio` /
|
package/types/ui-config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui-config.d.ts","sourceRoot":"","sources":["../../src/types/ui-config.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ui-config.d.ts","sourceRoot":"","sources":["../../src/types/ui-config.ts"],"names":[],"mappings":"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"}
|