@frontmcp/uipack 1.3.0 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/adapters/index.js +1046 -698
  2. package/adapters/template-renderer.d.ts +14 -0
  3. package/adapters/template-renderer.d.ts.map +1 -1
  4. package/bridge-runtime/iife-generator.d.ts.map +1 -1
  5. package/bridge-runtime/index.js +149 -0
  6. package/component/index.d.ts +1 -0
  7. package/component/index.d.ts.map +1 -1
  8. package/component/index.js +468 -145
  9. package/component/loader.d.ts +21 -2
  10. package/component/loader.d.ts.map +1 -1
  11. package/component/renderer.d.ts +2 -2
  12. package/component/renderer.d.ts.map +1 -1
  13. package/component/transpiler.d.ts +16 -1
  14. package/component/transpiler.d.ts.map +1 -1
  15. package/component/types.d.ts +19 -0
  16. package/component/types.d.ts.map +1 -1
  17. package/component/ui-availability.d.ts +27 -0
  18. package/component/ui-availability.d.ts.map +1 -0
  19. package/esm/adapters/index.mjs +1046 -698
  20. package/esm/bridge-runtime/index.mjs +149 -0
  21. package/esm/component/index.mjs +468 -145
  22. package/esm/index.mjs +444 -109
  23. package/esm/package.json +2 -2
  24. package/esm/shell/index.mjs +420 -171
  25. package/index.d.ts +1 -1
  26. package/index.d.ts.map +1 -1
  27. package/index.js +445 -109
  28. package/package.json +2 -2
  29. package/shell/builder.d.ts.map +1 -1
  30. package/shell/data-injector.d.ts +27 -1
  31. package/shell/data-injector.d.ts.map +1 -1
  32. package/shell/index.d.ts +3 -2
  33. package/shell/index.d.ts.map +1 -1
  34. package/shell/index.js +423 -171
  35. package/shell/sizing-css.d.ts +27 -0
  36. package/shell/sizing-css.d.ts.map +1 -0
  37. package/shell/types.d.ts +102 -0
  38. package/shell/types.d.ts.map +1 -1
  39. package/types/index.d.ts +1 -1
  40. package/types/index.d.ts.map +1 -1
  41. package/types/ui-config.d.ts +105 -11
  42. package/types/ui-config.d.ts.map +1 -1
  43. package/types/ui-runtime.d.ts +23 -2
  44. package/types/ui-runtime.d.ts.map +1 -1
@@ -52,6 +52,8 @@ function generateBridgeIIFE(options = {}) {
52
52
  parts.push("});");
53
53
  parts.push("");
54
54
  parts.push("window.FrontMcpBridge = bridge;");
55
+ parts.push("");
56
+ parts.push(generateAutoResize());
55
57
  parts.push("function __showLoading() {");
56
58
  parts.push(' var root = document.getElementById("root");');
57
59
  parts.push(" if (root && !root.hasChildNodes()) {");
@@ -72,6 +74,112 @@ function generateBridgeIIFE(options = {}) {
72
74
  }
73
75
  return code;
74
76
  }
77
+ function generateAutoResize() {
78
+ return `
79
+ function __applySizingCss(sizing) {
80
+ if (typeof document === 'undefined' || !document.documentElement) return;
81
+ function toLen(v) { return typeof v === 'number' ? v + 'px' : v; }
82
+ var de = document.documentElement;
83
+ var body = document.body;
84
+ var root = document.getElementById('root');
85
+ if (sizing.preferredHeight != null) {
86
+ var ph = toLen(sizing.preferredHeight);
87
+ de.style.height = ph;
88
+ if (body) body.style.height = ph;
89
+ if (root && !root.style.minHeight) root.style.minHeight = ph;
90
+ }
91
+ if (sizing.minHeight != null) {
92
+ var mh = toLen(sizing.minHeight);
93
+ de.style.minHeight = mh;
94
+ if (body) body.style.minHeight = mh;
95
+ if (root) root.style.minHeight = mh;
96
+ }
97
+ if (sizing.maxHeight != null) {
98
+ var mx = toLen(sizing.maxHeight);
99
+ de.style.maxHeight = mx;
100
+ if (body) body.style.maxHeight = mx;
101
+ if (root) root.style.maxHeight = mx;
102
+ }
103
+ if (sizing.aspectRatio != null && root) {
104
+ root.style.aspectRatio = String(sizing.aspectRatio);
105
+ }
106
+ }
107
+
108
+ function __initAutoResize() {
109
+ if (typeof window === 'undefined') return;
110
+ // Idempotent: a re-injected IIFE must not stack observers.
111
+ if (window.__mcpAutoResizeInit) return;
112
+ window.__mcpAutoResizeInit = true;
113
+ var sizing = window.__mcpWidgetSizing;
114
+ if (!sizing || typeof sizing !== 'object') return;
115
+
116
+ // Apply CSS as a runtime fallback (the static <style> may be absent on some
117
+ // render paths). Wait for the body if it isn't ready yet.
118
+ function apply() { try { __applySizingCss(sizing); } catch (e) {} }
119
+ if (typeof document !== 'undefined' && document.readyState === 'loading') {
120
+ document.addEventListener('DOMContentLoaded', apply);
121
+ } else {
122
+ apply();
123
+ }
124
+
125
+ // Auto-resize defaults ON; opt out with autoResize:false.
126
+ if (sizing.autoResize === false) return;
127
+ if (typeof ResizeObserver === 'undefined') return;
128
+
129
+ function startObserving() {
130
+ var target = document.getElementById('root') || document.body;
131
+ if (!target) return;
132
+
133
+ var rafId = null;
134
+ var lastReported = -1;
135
+ function report() {
136
+ rafId = null;
137
+ try {
138
+ var rect = target.getBoundingClientRect();
139
+ var height = Math.ceil(rect.height);
140
+ var width = Math.ceil(rect.width);
141
+ if (height === lastReported || height <= 0) return;
142
+ lastReported = height;
143
+ var payload = { height: height, width: width };
144
+ if (sizing.aspectRatio != null) payload.aspectRatio = sizing.aspectRatio;
145
+ if (window.FrontMcpBridge && typeof window.FrontMcpBridge.setSize === 'function') {
146
+ window.FrontMcpBridge.setSize(payload).catch(function() {});
147
+ }
148
+ window.dispatchEvent(new CustomEvent('widget:resize', { detail: payload }));
149
+ } catch (e) {}
150
+ }
151
+ function schedule() {
152
+ // Debounce via rAF; fall back to setTimeout if rAF is unavailable.
153
+ if (rafId != null) return;
154
+ if (typeof requestAnimationFrame === 'function') {
155
+ rafId = requestAnimationFrame(report);
156
+ } else {
157
+ rafId = setTimeout(report, 100);
158
+ }
159
+ }
160
+
161
+ try {
162
+ // Disconnect any prior observer before creating a new one (no leaks/dupes).
163
+ if (window.__mcpResizeObserver && typeof window.__mcpResizeObserver.disconnect === 'function') {
164
+ window.__mcpResizeObserver.disconnect();
165
+ }
166
+ var ro = new ResizeObserver(function() { schedule(); });
167
+ ro.observe(target);
168
+ window.__mcpResizeObserver = ro;
169
+ } catch (e) {}
170
+ // Report once on init so the host gets an initial measurement.
171
+ schedule();
172
+ }
173
+
174
+ if (typeof document !== 'undefined' && document.readyState === 'loading') {
175
+ document.addEventListener('DOMContentLoaded', startObserving);
176
+ } else {
177
+ startObserving();
178
+ }
179
+ }
180
+ __initAutoResize();
181
+ `.trim();
182
+ }
75
183
  function generateContextDetection() {
76
184
  return `
77
185
  function detectTheme() {
@@ -179,6 +287,19 @@ var OpenAIAdapter = {
179
287
  requestDisplayMode: function(context, mode) {
180
288
  return Promise.resolve();
181
289
  },
290
+ setSize: function(context, size) {
291
+ // OpenAI Apps SDK measures DOM height itself; if a sizing API surfaces on
292
+ // window.openai, forward to it, otherwise no-op (CSS drives layout).
293
+ try {
294
+ if (window.openai && typeof window.openai.requestDisplayMode === 'function' && size && size.displayMode) {
295
+ window.openai.requestDisplayMode(size.displayMode);
296
+ }
297
+ if (window.openai && typeof window.openai.setWidgetHeight === 'function' && size && typeof size.height === 'number') {
298
+ window.openai.setWidgetHeight(size.height);
299
+ }
300
+ } catch (e) {}
301
+ return Promise.resolve();
302
+ },
182
303
  requestClose: function(context) {
183
304
  return Promise.resolve();
184
305
  }
@@ -423,6 +544,15 @@ var ExtAppsAdapter = {
423
544
  requestDisplayMode: function(context, mode) {
424
545
  return this.sendRequest('ui/setDisplayMode', { mode: mode });
425
546
  },
547
+ setSize: function(context, size) {
548
+ // FrontMCP sizing channel \u2014 parallels ui/setDisplayMode. Reports the
549
+ // measured/desired widget dimensions to the host.
550
+ return this.sendRequest('ui/setSize', {
551
+ height: size && size.height,
552
+ width: size && size.width,
553
+ aspectRatio: size && size.aspectRatio
554
+ });
555
+ },
426
556
  requestClose: function(context) {
427
557
  return this.sendRequest('ui/close', {});
428
558
  },
@@ -511,6 +641,10 @@ var ClaudeAdapter = {
511
641
  requestDisplayMode: function() {
512
642
  return Promise.resolve();
513
643
  },
644
+ setSize: function() {
645
+ // Claude measures the rendered DOM height itself \u2014 CSS-only, no reporting.
646
+ return Promise.resolve();
647
+ },
514
648
  requestClose: function() {
515
649
  return Promise.resolve();
516
650
  }
@@ -562,6 +696,9 @@ var GeminiAdapter = {
562
696
  requestDisplayMode: function() {
563
697
  return Promise.resolve();
564
698
  },
699
+ setSize: function() {
700
+ return Promise.resolve();
701
+ },
565
702
  requestClose: function() {
566
703
  return Promise.resolve();
567
704
  }
@@ -597,6 +734,9 @@ var GenericAdapter = {
597
734
  requestDisplayMode: function() {
598
735
  return Promise.resolve();
599
736
  },
737
+ setSize: function() {
738
+ return Promise.resolve();
739
+ },
600
740
  requestClose: function() {
601
741
  return Promise.resolve();
602
742
  }
@@ -831,6 +971,15 @@ FrontMcpBridge.prototype.requestDisplayMode = function(mode) {
831
971
  });
832
972
  };
833
973
 
974
+ // Report a desired widget size to the host. \`size\` is { height?, width?, aspectRatio? }.
975
+ // Per-adapter behaviour: Claude/generic no-op (host measures the DOM),
976
+ // ext-apps sends ui/setSize, OpenAI forwards to its SDK when available.
977
+ FrontMcpBridge.prototype.setSize = function(size) {
978
+ if (!this._adapter) return Promise.reject(new Error('Not initialized'));
979
+ if (!this._adapter.setSize) return Promise.resolve();
980
+ return this._adapter.setSize(this._context, size || {});
981
+ };
982
+
834
983
  FrontMcpBridge.prototype.requestClose = function() {
835
984
  if (!this._adapter) return Promise.reject(new Error('Not initialized'));
836
985
  return this._adapter.requestClose(this._context);