@tylertech/forge-ai 0.15.1 → 0.15.3-dev.0

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 (71) hide show
  1. package/custom-elements.json +8152 -6309
  2. package/dist/ai-artifact-card/ai-artifact-card.d.ts +75 -0
  3. package/dist/ai-artifact-card/ai-artifact-card.mjs +142 -0
  4. package/dist/ai-artifact-card/ai-artifact-card.scss.mjs +283 -0
  5. package/dist/ai-artifact-card/index.d.ts +1 -0
  6. package/dist/ai-artifact-card/index.mjs +5 -0
  7. package/dist/ai-artifact-card-group/ai-artifact-card-group.d.ts +57 -0
  8. package/dist/ai-artifact-card-group/ai-artifact-card-group.mjs +137 -0
  9. package/dist/ai-artifact-card-group/ai-artifact-card-group.scss.mjs +173 -0
  10. package/dist/ai-artifact-card-group/index.d.ts +1 -0
  11. package/dist/ai-artifact-card-group/index.mjs +5 -0
  12. package/dist/ai-assistant-response/ai-assistant-response.mjs +25 -2
  13. package/dist/ai-chatbot/ag-ui-adapter.mjs +1 -1
  14. package/dist/ai-chatbot/agent-adapter.d.ts +108 -1
  15. package/dist/ai-chatbot/agent-adapter.mjs +22 -0
  16. package/dist/ai-chatbot/ai-chatbot-base.d.ts +26 -0
  17. package/dist/ai-chatbot/ai-chatbot-base.mjs +136 -3
  18. package/dist/ai-chatbot/index.d.ts +2 -2
  19. package/dist/ai-chatbot/message-state-controller.d.ts +10 -1
  20. package/dist/ai-chatbot/message-state-controller.mjs +78 -20
  21. package/dist/ai-chatbot/types.d.ts +199 -1
  22. package/dist/ai-chatbot/utils.mjs +3 -1
  23. package/dist/ai-chatbot-launcher/ai-chatbot-launcher.mjs +14 -4
  24. package/dist/ai-message-thread/ai-message-thread.d.ts +1 -0
  25. package/dist/ai-message-thread/ai-message-thread.mjs +35 -3
  26. package/dist/ai-sidebar/ai-sidebar.d.ts +17 -6
  27. package/dist/ai-sidebar/ai-sidebar.mjs +78 -36
  28. package/dist/ai-sidebar/ai-sidebar.scss.mjs +1 -1
  29. package/dist/ai-sidebar/index.d.ts +1 -0
  30. package/dist/ai-sidebar-chat/ai-sidebar-chat.d.ts +14 -1
  31. package/dist/ai-sidebar-chat/ai-sidebar-chat.mjs +18 -14
  32. package/dist/ai-steps/ai-steps.d.ts +67 -0
  33. package/dist/ai-steps/ai-steps.mjs +163 -0
  34. package/dist/ai-steps/ai-steps.scss.mjs +4 -0
  35. package/dist/ai-steps/index.d.ts +1 -0
  36. package/dist/ai-steps/index.mjs +5 -0
  37. package/dist/ai-tool-call-indicator/ai-tool-call-indicator.mjs +1 -1
  38. package/dist/core/chatbot-core-controller.d.ts +2 -0
  39. package/dist/core/chatbot-core-controller.mjs +99 -4
  40. package/dist/core/resize-controller.d.ts +1 -0
  41. package/dist/core/resize-controller.mjs +11 -2
  42. package/dist/index.d.ts +3 -0
  43. package/dist/index.mjs +9 -0
  44. package/dist/tools/ai-mcp-app/ai-mcp-app.d.ts +69 -0
  45. package/dist/tools/ai-mcp-app/ai-mcp-app.mjs +574 -0
  46. package/dist/tools/ai-mcp-app/ai-mcp-app.scss.mjs +4 -0
  47. package/dist/tools/ai-mcp-app/index.d.ts +3 -0
  48. package/dist/tools/ai-mcp-app/index.mjs +6 -0
  49. package/dist/tools/ai-mcp-app/mcp-app-bridge-controller.d.ts +61 -0
  50. package/dist/tools/ai-mcp-app/mcp-app-bridge-controller.mjs +156 -0
  51. package/dist/tools/ai-mcp-app/mcp-app-bridge-types.d.ts +123 -0
  52. package/dist/tools/ai-mcp-app/mcp-app-bridge.d.ts +41 -0
  53. package/dist/tools/ai-mcp-app/mcp-app-bridge.mjs +293 -0
  54. package/dist/tools/ai-mcp-app/mcp-app-context.d.ts +46 -0
  55. package/dist/tools/ai-mcp-app/mcp-app-context.mjs +5 -0
  56. package/dist/tools/ai-steps/ai-steps-definition.d.ts +2 -0
  57. package/dist/tools/ai-steps/ai-steps-definition.mjs +50 -0
  58. package/dist/tools/ai-steps/ai-steps.d.ts +28 -0
  59. package/dist/tools/ai-steps/ai-steps.mjs +49 -0
  60. package/dist/tools/ai-steps/ai-steps.scss.mjs +4 -0
  61. package/dist/tools/ai-steps/index.d.ts +2 -0
  62. package/dist/tools/ai-steps/index.mjs +6 -0
  63. package/dist/tools/index.d.ts +1 -0
  64. package/dist/tools/index.mjs +5 -1
  65. package/dist/utils/index.d.ts +1 -0
  66. package/dist/utils/index.mjs +5 -1
  67. package/dist/utils/inert-outside.d.ts +7 -0
  68. package/dist/utils/inert-outside.mjs +28 -0
  69. package/dist/utils/storage-utils.d.ts +26 -0
  70. package/dist/utils/storage-utils.mjs +32 -0
  71. package/package.json +4 -1
@@ -0,0 +1,69 @@
1
+ import { LitElement, PropertyValues, TemplateResult, nothing, CSSResult } from 'lit';
2
+ import { IToolRenderer, McpAppDisplayMode, McpModelContextUpdateParams, ToolCall, ToolDefinition } from '../../ai-chatbot';
3
+ import { McpAppLoggingMessage } from './mcp-app-bridge-types.js';
4
+ import { McpAppHost } from './mcp-app-context.js';
5
+ declare global {
6
+ interface HTMLElementTagNameMap {
7
+ 'forge-ai-mcp-app': McpAppToolElement;
8
+ }
9
+ interface HTMLElementEventMap {
10
+ 'forge-ai-mcp-app-open-link': CustomEvent<{
11
+ url: string;
12
+ }>;
13
+ 'forge-ai-mcp-app-message': CustomEvent<{
14
+ content: unknown[];
15
+ role: 'user';
16
+ }>;
17
+ 'forge-ai-mcp-app-logging-message': CustomEvent<McpAppLoggingMessage>;
18
+ 'forge-ai-mcp-app-request-teardown': CustomEvent<{
19
+ toolCallId: string;
20
+ }>;
21
+ 'forge-ai-mcp-app-request-display-mode': CustomEvent<{
22
+ mode: McpAppDisplayMode;
23
+ }>;
24
+ 'forge-ai-mcp-app-update-model-context': CustomEvent<McpModelContextUpdateParams>;
25
+ }
26
+ }
27
+ /**
28
+ * Renders an MCP-app UI resource stamped onto a {@link ToolCall} as a sandboxed,
29
+ * cross-origin widget. The iframe + bridge are mounted once and survive every `toolCall`
30
+ * delta (Lit reuses this node at its keyed position), so args stream live without
31
+ * remounting.
32
+ *
33
+ * The cross-origin sandbox is mandatory: when no `sandboxUrl` is available the element
34
+ * renders an error artifact rather than an insecure same-origin iframe.
35
+ *
36
+ * @tag forge-ai-mcp-app
37
+ * @internal
38
+ *
39
+ * @event {CustomEvent<{ url: string }>} forge-ai-mcp-app-open-link - Fired (cancelable) when the app requests to open an http(s)/mailto link; unless `preventDefault()` is called, the user is asked to confirm and the link opens in a new tab
40
+ * @event {CustomEvent<{ content: unknown[]; role: 'user' }>} forge-ai-mcp-app-message - Fired when the app sends a `ui/message`, before its text is placed in the prompt for the user to send
41
+ * @event {CustomEvent<McpAppLoggingMessage>} forge-ai-mcp-app-logging-message - Fired (cancelable) when the app sends a logging message; logged to the console unless `preventDefault()` is called
42
+ * @event {CustomEvent<{ toolCallId: string }>} forge-ai-mcp-app-request-teardown - Fired (cancelable) when the app asks to be torn down; the host tears the widget down unless `preventDefault()` is called
43
+ * @event {CustomEvent<{ mode: McpAppDisplayMode }>} forge-ai-mcp-app-request-display-mode - Fired when the app's display mode changes
44
+ * @event {CustomEvent<McpModelContextUpdateParams>} forge-ai-mcp-app-update-model-context - Fired when the app updates model context; detail carries `toolCallId`, `content` and `structuredContent`
45
+ */
46
+ export declare class McpAppToolElement extends LitElement implements IToolRenderer {
47
+ #private;
48
+ static styles: CSSResult;
49
+ toolCall: ToolCall;
50
+ /** Client-side definition of the tool, when one is registered; supplies `toolInfo.tool`. */
51
+ toolDefinition?: ToolDefinition;
52
+ host?: McpAppHost;
53
+ private _iframe;
54
+ private _container;
55
+ private _displayMode;
56
+ private _lifecycle;
57
+ private _pendingLink;
58
+ firstUpdated(): void;
59
+ updated(changedProperties: PropertyValues): void;
60
+ connectedCallback(): void;
61
+ disconnectedCallback(): void;
62
+ /**
63
+ * Send `ui/resource-teardown` to the View and release the bridge without waiting for the
64
+ * ack. The chatbot calls this when removing widgets; it also runs on disconnect as a
65
+ * fallback. A later `toolCall` update remounts the widget.
66
+ */
67
+ teardown(): void;
68
+ render(): TemplateResult | typeof nothing;
69
+ }
@@ -0,0 +1,574 @@
1
+ import { consume } from "@lit/context";
2
+ import { unsafeCSS, LitElement, html, nothing } from "lit";
3
+ import { property, query, state, customElement } from "lit/decorators.js";
4
+ import { classMap } from "lit/directives/class-map.js";
5
+ import { inertOutside } from "../../utils/inert-outside.mjs";
6
+ import { McpAppBridge } from "./mcp-app-bridge.mjs";
7
+ import { mcpAppHostContext } from "./mcp-app-context.mjs";
8
+ import { McpAppBridgeController, enforcedPermissions } from "./mcp-app-bridge-controller.mjs";
9
+ import "../../ai-empty-state/ai-empty-state.mjs";
10
+ import "../../ai-confirmation-prompt/ai-confirmation-prompt.mjs";
11
+ import styles from "./ai-mcp-app.scss.mjs";
12
+ var __defProp = Object.defineProperty;
13
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
14
+ var __typeError = (msg) => {
15
+ throw TypeError(msg);
16
+ };
17
+ var __decorateClass = (decorators, target, key, kind) => {
18
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
19
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
20
+ if (decorator = decorators[i])
21
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
22
+ if (kind && result) __defProp(target, key, result);
23
+ return result;
24
+ };
25
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
26
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
27
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
28
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
29
+ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
30
+ var _controller, _lastHostContext, _unregisterView, _containerDimensions, _hostStyles, _restorePage, _resizeFrame, _resizeObserver, _McpAppToolElement_instances, uiResource_get, hasPolicy_get, canRender_get, canConnect_get, errorBody_get, hostContext_get, toolInfo_get, hostCapabilities_get, handlers_get, setDisplayMode_fn, applyDisplayMode_fn, releasePage_fn, connect_fn, syncHostContext_fn, resolveHostStyles_fn, scheduleContainerMeasure_fn, cancelContainerMeasure_fn, readContainerDimensions_fn, measureContainer_fn, openLink_fn, settlePendingLink_fn, confirmLink_fn, dispatchMessage_fn, handleLoggingMessage_fn, handleRequestTeardown_fn, dispatchRequestDisplayMode_fn, dispatchUpdateModelContext_fn, _iframe, _promotedToolbar, linkConfirmation_get, isPromoted_get, exitToInline_fn, handleContainerKeydown_fn, bordered_get, errorArtifact_get;
31
+ const HOST_INFO = { name: "forge-ai", version: "1.0.0" };
32
+ const MAX_INLINE_HEIGHT = 2e3;
33
+ const OPEN_LINK_PROTOCOLS = ["http:", "https:", "mailto:"];
34
+ const HOST_STYLE_KEYS = [
35
+ "color-background-primary",
36
+ "color-background-secondary",
37
+ "color-background-tertiary",
38
+ "color-background-inverse",
39
+ "color-background-info",
40
+ "color-background-danger",
41
+ "color-background-success",
42
+ "color-background-warning",
43
+ "color-text-primary",
44
+ "color-text-secondary",
45
+ "color-text-tertiary",
46
+ "color-text-inverse",
47
+ "color-text-info",
48
+ "color-text-danger",
49
+ "color-text-success",
50
+ "color-text-warning",
51
+ "color-text-disabled",
52
+ "color-border-primary",
53
+ "color-border-secondary",
54
+ "color-border-info",
55
+ "color-border-danger",
56
+ "color-border-success",
57
+ "color-border-warning",
58
+ "color-ring-primary",
59
+ "font-sans",
60
+ "font-weight-normal",
61
+ "font-weight-medium",
62
+ "font-weight-bold",
63
+ "font-text-xs-size",
64
+ "font-text-sm-size",
65
+ "font-text-md-size",
66
+ "font-text-lg-size",
67
+ "font-text-xs-line-height",
68
+ "font-text-sm-line-height",
69
+ "font-text-md-line-height",
70
+ "font-text-lg-line-height",
71
+ "font-heading-sm-size",
72
+ "font-heading-md-size",
73
+ "font-heading-lg-size",
74
+ "font-heading-xl-size",
75
+ "font-heading-2xl-size",
76
+ "font-heading-3xl-size",
77
+ "font-heading-sm-line-height",
78
+ "font-heading-md-line-height",
79
+ "font-heading-lg-line-height",
80
+ "font-heading-xl-line-height",
81
+ "font-heading-2xl-line-height",
82
+ "font-heading-3xl-line-height",
83
+ "border-radius-xs",
84
+ "border-radius-sm",
85
+ "border-radius-md",
86
+ "border-radius-lg",
87
+ "border-radius-xl",
88
+ "border-radius-full",
89
+ "border-width-regular",
90
+ "shadow-sm",
91
+ "shadow-md",
92
+ "shadow-lg"
93
+ ];
94
+ const CONSOLE_LEVELS = {
95
+ debug: "debug",
96
+ info: "info",
97
+ notice: "info",
98
+ warning: "warn",
99
+ error: "error",
100
+ critical: "error",
101
+ alert: "error",
102
+ emergency: "error"
103
+ };
104
+ function asOpenableUrl(url) {
105
+ try {
106
+ const parsed = new URL(url);
107
+ return OPEN_LINK_PROTOCOLS.includes(parsed.protocol) ? parsed.href : null;
108
+ } catch {
109
+ return null;
110
+ }
111
+ }
112
+ let McpAppToolElement = class extends LitElement {
113
+ constructor() {
114
+ super(...arguments);
115
+ __privateAdd(this, _McpAppToolElement_instances);
116
+ this._displayMode = "inline";
117
+ this._lifecycle = "live";
118
+ this._pendingLink = null;
119
+ __privateAdd(this, _controller, null);
120
+ __privateAdd(this, _lastHostContext, null);
121
+ __privateAdd(this, _unregisterView, null);
122
+ __privateAdd(this, _containerDimensions, { maxHeight: MAX_INLINE_HEIGHT });
123
+ __privateAdd(this, _hostStyles, {});
124
+ __privateAdd(this, _restorePage, null);
125
+ __privateAdd(this, _resizeFrame, null);
126
+ __privateAdd(this, _resizeObserver, new ResizeObserver(() => __privateMethod(this, _McpAppToolElement_instances, scheduleContainerMeasure_fn).call(this)));
127
+ __privateAdd(this, _iframe, html`<iframe title="MCP application" sandbox="allow-scripts allow-same-origin"></iframe>`);
128
+ __privateAdd(this, _promotedToolbar, html`
129
+ <div class="promoted-toolbar">
130
+ <button
131
+ class="forge-icon-button forge-icon-button--medium exit-button"
132
+ aria-label="Exit to inline view"
133
+ @click=${() => __privateMethod(this, _McpAppToolElement_instances, exitToInline_fn).call(this)}>
134
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true">
135
+ <path fill="none" d="M0 0h24v24H0z" />
136
+ <path
137
+ d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" />
138
+ </svg>
139
+ </button>
140
+ </div>
141
+ `);
142
+ }
143
+ firstUpdated() {
144
+ __privateMethod(this, _McpAppToolElement_instances, connect_fn).call(this);
145
+ }
146
+ updated(changedProperties) {
147
+ if (!__privateGet(this, _controller)) {
148
+ __privateMethod(this, _McpAppToolElement_instances, connect_fn).call(this);
149
+ return;
150
+ }
151
+ __privateGet(this, _controller).syncToolCall(this.toolCall);
152
+ if (changedProperties.has("_displayMode")) {
153
+ __privateMethod(this, _McpAppToolElement_instances, applyDisplayMode_fn).call(this);
154
+ __privateSet(this, _containerDimensions, __privateMethod(this, _McpAppToolElement_instances, readContainerDimensions_fn).call(this) ?? __privateGet(this, _containerDimensions));
155
+ }
156
+ __privateMethod(this, _McpAppToolElement_instances, syncHostContext_fn).call(this, changedProperties);
157
+ }
158
+ connectedCallback() {
159
+ super.connectedCallback();
160
+ if (this.hasUpdated && !__privateGet(this, _controller)) {
161
+ this.requestUpdate();
162
+ }
163
+ }
164
+ disconnectedCallback() {
165
+ super.disconnectedCallback();
166
+ __privateGet(this, _resizeObserver).disconnect();
167
+ __privateMethod(this, _McpAppToolElement_instances, cancelContainerMeasure_fn).call(this);
168
+ __privateMethod(this, _McpAppToolElement_instances, releasePage_fn).call(this);
169
+ this.teardown();
170
+ }
171
+ /**
172
+ * Send `ui/resource-teardown` to the View and release the bridge without waiting for the
173
+ * ack. The chatbot calls this when removing widgets; it also runs on disconnect as a
174
+ * fallback. A later `toolCall` update remounts the widget.
175
+ */
176
+ teardown() {
177
+ var _a;
178
+ __privateMethod(this, _McpAppToolElement_instances, settlePendingLink_fn).call(this, { isError: true });
179
+ (_a = __privateGet(this, _unregisterView)) == null ? void 0 : _a.call(this);
180
+ __privateSet(this, _unregisterView, null);
181
+ const controller = __privateGet(this, _controller);
182
+ __privateSet(this, _controller, null);
183
+ controller?.teardown();
184
+ }
185
+ render() {
186
+ if (this._lifecycle === "closed") {
187
+ return nothing;
188
+ }
189
+ if (!__privateGet(this, _McpAppToolElement_instances, canRender_get)) {
190
+ return __privateGet(this, _McpAppToolElement_instances, errorArtifact_get);
191
+ }
192
+ return html`
193
+ <div
194
+ class=${classMap({
195
+ container: true,
196
+ bordered: __privateGet(this, _McpAppToolElement_instances, bordered_get),
197
+ fullscreen: this._displayMode === "fullscreen",
198
+ pip: this._displayMode === "pip"
199
+ })}
200
+ popover="manual"
201
+ role=${__privateGet(this, _McpAppToolElement_instances, isPromoted_get) ? "dialog" : nothing}
202
+ aria-label=${__privateGet(this, _McpAppToolElement_instances, isPromoted_get) ? "MCP application" : nothing}
203
+ data-handles-escape
204
+ @keydown=${__privateMethod(this, _McpAppToolElement_instances, handleContainerKeydown_fn)}>
205
+ ${__privateGet(this, _McpAppToolElement_instances, isPromoted_get) ? __privateGet(this, _promotedToolbar) : nothing} ${__privateGet(this, _iframe)} ${__privateGet(this, _McpAppToolElement_instances, linkConfirmation_get)}
206
+ </div>
207
+ `;
208
+ }
209
+ };
210
+ _controller = /* @__PURE__ */ new WeakMap();
211
+ _lastHostContext = /* @__PURE__ */ new WeakMap();
212
+ _unregisterView = /* @__PURE__ */ new WeakMap();
213
+ _containerDimensions = /* @__PURE__ */ new WeakMap();
214
+ _hostStyles = /* @__PURE__ */ new WeakMap();
215
+ _restorePage = /* @__PURE__ */ new WeakMap();
216
+ _resizeFrame = /* @__PURE__ */ new WeakMap();
217
+ _resizeObserver = /* @__PURE__ */ new WeakMap();
218
+ _McpAppToolElement_instances = /* @__PURE__ */ new WeakSet();
219
+ uiResource_get = function() {
220
+ return this.toolCall?.uiResource;
221
+ };
222
+ hasPolicy_get = function() {
223
+ const resource = __privateGet(this, _McpAppToolElement_instances, uiResource_get);
224
+ return !!resource && resource.csp !== void 0 && resource.permissions !== void 0;
225
+ };
226
+ canRender_get = function() {
227
+ return !!__privateGet(this, _McpAppToolElement_instances, uiResource_get)?.html && !!this.host?.sandboxUrl && __privateGet(this, _McpAppToolElement_instances, hasPolicy_get);
228
+ };
229
+ canConnect_get = function() {
230
+ return this._lifecycle === "live" && __privateGet(this, _McpAppToolElement_instances, canRender_get);
231
+ };
232
+ errorBody_get = function() {
233
+ if (!this.host?.sandboxUrl) {
234
+ return "This interactive app can't be shown because no secure sandbox is configured.";
235
+ }
236
+ return "This interactive app can't be shown because its security policy is missing.";
237
+ };
238
+ hostContext_get = function() {
239
+ return {
240
+ ...this.host?.hostContext ?? { theme: "light" },
241
+ styles: __privateGet(this, _hostStyles),
242
+ toolInfo: __privateGet(this, _McpAppToolElement_instances, toolInfo_get),
243
+ containerDimensions: __privateGet(this, _containerDimensions),
244
+ displayMode: this._displayMode
245
+ };
246
+ };
247
+ toolInfo_get = function() {
248
+ const definition = this.toolDefinition;
249
+ return {
250
+ id: this.toolCall.id,
251
+ tool: {
252
+ name: this.toolCall.name,
253
+ ...definition?.description ? { description: definition.description } : {},
254
+ ...definition?.displayName ? { title: definition.displayName } : {},
255
+ inputSchema: { ...definition?.parameters, type: "object" }
256
+ }
257
+ };
258
+ };
259
+ hostCapabilities_get = function() {
260
+ const resource = __privateGet(this, _McpAppToolElement_instances, uiResource_get);
261
+ return {
262
+ ...this.host?.hostCapabilities,
263
+ sandbox: {
264
+ csp: resource?.csp ?? {},
265
+ permissions: enforcedPermissions(resource?.permissions ?? {})
266
+ }
267
+ };
268
+ };
269
+ handlers_get = function() {
270
+ const unavailable = () => Promise.reject(new Error("MCP app host is unavailable"));
271
+ return {
272
+ oncalltool: (params) => this.host?.callTool({ ...params, toolCallId: this.toolCall.id }) ?? unavailable(),
273
+ onreadresource: (params) => this.host?.readResource({ ...params, toolCallId: this.toolCall.id }) ?? unavailable(),
274
+ onopenlink: ({ url }) => __privateMethod(this, _McpAppToolElement_instances, openLink_fn).call(this, url),
275
+ onmessage: async ({ content, role }) => {
276
+ __privateMethod(this, _McpAppToolElement_instances, dispatchMessage_fn).call(this, content, role);
277
+ return this.host?.draftMessage({ toolCallId: this.toolCall.id, content }) ?? { isError: true };
278
+ },
279
+ onloggingmessage: (message) => __privateMethod(this, _McpAppToolElement_instances, handleLoggingMessage_fn).call(this, message),
280
+ onsizechange: ({ height }) => {
281
+ if (height > 0 && this._displayMode === "inline") {
282
+ this.style.height = `${Math.min(height, MAX_INLINE_HEIGHT)}px`;
283
+ }
284
+ },
285
+ onrequestdisplaymode: async ({ mode, appDisplayModes }) => {
286
+ const resultMode = __privateMethod(this, _McpAppToolElement_instances, setDisplayMode_fn).call(this, mode, appDisplayModes);
287
+ __privateMethod(this, _McpAppToolElement_instances, dispatchRequestDisplayMode_fn).call(this, resultMode);
288
+ return { mode: resultMode };
289
+ },
290
+ onupdatemodelcontext: async ({ content, structuredContent }) => {
291
+ const params = { toolCallId: this.toolCall.id, content, structuredContent };
292
+ __privateMethod(this, _McpAppToolElement_instances, dispatchUpdateModelContext_fn).call(this, params);
293
+ await this.host?.updateModelContext(params);
294
+ },
295
+ onrequestteardown: () => __privateMethod(this, _McpAppToolElement_instances, handleRequestTeardown_fn).call(this)
296
+ };
297
+ };
298
+ setDisplayMode_fn = function(requested, appDisplayModes) {
299
+ const hostModes = this.host?.hostContext.availableDisplayModes ?? [];
300
+ const allowed = requested === "inline" || hostModes.includes(requested) && appDisplayModes.includes(requested);
301
+ if (allowed) {
302
+ this._displayMode = requested;
303
+ }
304
+ return this._displayMode;
305
+ };
306
+ applyDisplayMode_fn = function() {
307
+ const container = this._container;
308
+ if (!container) {
309
+ return;
310
+ }
311
+ if (this._displayMode === "inline") {
312
+ if (container.matches(":popover-open")) {
313
+ container.hidePopover();
314
+ }
315
+ } else if (!container.matches(":popover-open")) {
316
+ container.showPopover();
317
+ }
318
+ __privateMethod(this, _McpAppToolElement_instances, releasePage_fn).call(this);
319
+ if (this._displayMode === "fullscreen") {
320
+ __privateSet(this, _restorePage, inertOutside(this));
321
+ }
322
+ if (__privateGet(this, _McpAppToolElement_instances, isPromoted_get)) {
323
+ this.updateComplete.then(() => this.renderRoot.querySelector(".exit-button")?.focus());
324
+ }
325
+ };
326
+ releasePage_fn = function() {
327
+ var _a;
328
+ (_a = __privateGet(this, _restorePage)) == null ? void 0 : _a.call(this);
329
+ __privateSet(this, _restorePage, null);
330
+ };
331
+ connect_fn = function() {
332
+ if (__privateGet(this, _controller) || !__privateGet(this, _McpAppToolElement_instances, canConnect_get)) {
333
+ return;
334
+ }
335
+ const iframe = this._iframe;
336
+ const resource = __privateGet(this, _McpAppToolElement_instances, uiResource_get);
337
+ const host = this.host;
338
+ if (!iframe || !resource || !host?.sandboxUrl) {
339
+ return;
340
+ }
341
+ const controller = new McpAppBridgeController(new McpAppBridge(HOST_INFO));
342
+ __privateSet(this, _controller, controller);
343
+ __privateSet(this, _containerDimensions, __privateMethod(this, _McpAppToolElement_instances, readContainerDimensions_fn).call(this) ?? __privateGet(this, _containerDimensions));
344
+ if (this._container) {
345
+ __privateGet(this, _resizeObserver).observe(this._container);
346
+ }
347
+ __privateSet(this, _lastHostContext, host.hostContext);
348
+ __privateSet(this, _hostStyles, __privateMethod(this, _McpAppToolElement_instances, resolveHostStyles_fn).call(this));
349
+ __privateSet(this, _unregisterView, host.registerView({ toolCallId: this.toolCall.id, teardown: () => this.teardown() }));
350
+ controller.connect({
351
+ iframe,
352
+ sandboxUrl: host.sandboxUrl,
353
+ html: resource.html,
354
+ hostContext: __privateGet(this, _McpAppToolElement_instances, hostContext_get),
355
+ hostCapabilities: __privateGet(this, _McpAppToolElement_instances, hostCapabilities_get),
356
+ csp: resource.csp,
357
+ permissions: resource.permissions,
358
+ handlers: __privateGet(this, _McpAppToolElement_instances, handlers_get)
359
+ }).then(() => controller.syncToolCall(this.toolCall)).catch((error) => console.warn("[forge-ai-mcp-app] Failed to connect widget:", error));
360
+ };
361
+ syncHostContext_fn = function(changedProperties) {
362
+ const next = this.host?.hostContext;
363
+ if (next && (next !== __privateGet(this, _lastHostContext) || changedProperties.has("_displayMode"))) {
364
+ __privateSet(this, _lastHostContext, next);
365
+ __privateSet(this, _hostStyles, __privateMethod(this, _McpAppToolElement_instances, resolveHostStyles_fn).call(this));
366
+ __privateGet(this, _controller)?.sendHostContextChange(__privateGet(this, _McpAppToolElement_instances, hostContext_get));
367
+ }
368
+ };
369
+ resolveHostStyles_fn = function() {
370
+ const computed = getComputedStyle(this);
371
+ const variables = {};
372
+ for (const key of HOST_STYLE_KEYS) {
373
+ const value = computed.getPropertyValue(`--_mcp-host-${key}`).trim();
374
+ if (value) {
375
+ variables[`--${key}`] = value;
376
+ }
377
+ }
378
+ return { variables };
379
+ };
380
+ scheduleContainerMeasure_fn = function() {
381
+ if (__privateGet(this, _resizeFrame) !== null) {
382
+ return;
383
+ }
384
+ __privateSet(this, _resizeFrame, requestAnimationFrame(() => {
385
+ __privateSet(this, _resizeFrame, null);
386
+ __privateMethod(this, _McpAppToolElement_instances, measureContainer_fn).call(this);
387
+ }));
388
+ };
389
+ cancelContainerMeasure_fn = function() {
390
+ if (__privateGet(this, _resizeFrame) !== null) {
391
+ cancelAnimationFrame(__privateGet(this, _resizeFrame));
392
+ __privateSet(this, _resizeFrame, null);
393
+ }
394
+ };
395
+ readContainerDimensions_fn = function() {
396
+ const container = this._container;
397
+ if (!container) {
398
+ return null;
399
+ }
400
+ const width = Math.round(container.clientWidth);
401
+ return this._displayMode === "inline" ? { width, maxHeight: MAX_INLINE_HEIGHT } : { width, height: Math.round(this._iframe?.clientHeight ?? container.clientHeight) };
402
+ };
403
+ measureContainer_fn = function() {
404
+ const next = __privateMethod(this, _McpAppToolElement_instances, readContainerDimensions_fn).call(this);
405
+ if (!next || JSON.stringify(next) === JSON.stringify(__privateGet(this, _containerDimensions))) {
406
+ return;
407
+ }
408
+ __privateSet(this, _containerDimensions, next);
409
+ __privateGet(this, _controller)?.sendHostContextChange(__privateGet(this, _McpAppToolElement_instances, hostContext_get));
410
+ };
411
+ openLink_fn = function(url) {
412
+ const href = asOpenableUrl(url);
413
+ if (!href) {
414
+ return Promise.resolve({ isError: true });
415
+ }
416
+ const event = new CustomEvent("forge-ai-mcp-app-open-link", {
417
+ detail: { url: href },
418
+ bubbles: true,
419
+ composed: true,
420
+ cancelable: true
421
+ });
422
+ if (!this.dispatchEvent(event)) {
423
+ return Promise.resolve({});
424
+ }
425
+ __privateMethod(this, _McpAppToolElement_instances, settlePendingLink_fn).call(this, { isError: true });
426
+ return new Promise((settle) => {
427
+ this._pendingLink = { href, settle };
428
+ });
429
+ };
430
+ settlePendingLink_fn = function(result) {
431
+ this._pendingLink?.settle(result);
432
+ this._pendingLink = null;
433
+ };
434
+ confirmLink_fn = function() {
435
+ const href = this._pendingLink?.href;
436
+ if (href) {
437
+ window.open(href, "_blank", "noopener,noreferrer");
438
+ }
439
+ __privateMethod(this, _McpAppToolElement_instances, settlePendingLink_fn).call(this, {});
440
+ };
441
+ dispatchMessage_fn = function(content, role) {
442
+ this.dispatchEvent(
443
+ new CustomEvent("forge-ai-mcp-app-message", { detail: { content, role }, bubbles: true, composed: true })
444
+ );
445
+ };
446
+ handleLoggingMessage_fn = function(message) {
447
+ const event = new CustomEvent("forge-ai-mcp-app-logging-message", {
448
+ detail: message,
449
+ bubbles: true,
450
+ composed: true,
451
+ cancelable: true
452
+ });
453
+ if (this.dispatchEvent(event)) {
454
+ const method = CONSOLE_LEVELS[message.level] ?? "info";
455
+ console[method](`[forge-ai-mcp-app]${message.logger ? ` [${message.logger}]` : ""}`, message.data);
456
+ }
457
+ };
458
+ handleRequestTeardown_fn = function() {
459
+ if (this._lifecycle !== "live") {
460
+ return;
461
+ }
462
+ const event = new CustomEvent("forge-ai-mcp-app-request-teardown", {
463
+ detail: { toolCallId: this.toolCall.id },
464
+ bubbles: true,
465
+ composed: true,
466
+ cancelable: true
467
+ });
468
+ if (!this.dispatchEvent(event)) {
469
+ return;
470
+ }
471
+ this._lifecycle = "closing";
472
+ __privateGet(this, _resizeObserver).disconnect();
473
+ __privateMethod(this, _McpAppToolElement_instances, cancelContainerMeasure_fn).call(this);
474
+ if (this.host) {
475
+ this.host.teardownView({ toolCallId: this.toolCall.id });
476
+ } else {
477
+ this.teardown();
478
+ }
479
+ this.style.removeProperty("height");
480
+ this._lifecycle = "closed";
481
+ };
482
+ dispatchRequestDisplayMode_fn = function(mode) {
483
+ this.dispatchEvent(
484
+ new CustomEvent("forge-ai-mcp-app-request-display-mode", { detail: { mode }, bubbles: true, composed: true })
485
+ );
486
+ };
487
+ dispatchUpdateModelContext_fn = function(detail) {
488
+ this.dispatchEvent(
489
+ new CustomEvent("forge-ai-mcp-app-update-model-context", { detail, bubbles: true, composed: true })
490
+ );
491
+ };
492
+ _iframe = /* @__PURE__ */ new WeakMap();
493
+ _promotedToolbar = /* @__PURE__ */ new WeakMap();
494
+ linkConfirmation_get = function() {
495
+ const link = this._pendingLink;
496
+ if (!link) {
497
+ return nothing;
498
+ }
499
+ return html`
500
+ <forge-ai-confirmation-prompt
501
+ text=${`Open this link in a new tab? ${link.href}`}
502
+ confirm-text="Open"
503
+ deny-text="Cancel"
504
+ @forge-ai-confirmation-prompt-confirm=${() => __privateMethod(this, _McpAppToolElement_instances, confirmLink_fn).call(this)}
505
+ @forge-ai-confirmation-prompt-deny=${() => __privateMethod(this, _McpAppToolElement_instances, settlePendingLink_fn).call(this, { isError: true })}>
506
+ </forge-ai-confirmation-prompt>
507
+ `;
508
+ };
509
+ isPromoted_get = function() {
510
+ return this._displayMode !== "inline";
511
+ };
512
+ exitToInline_fn = function() {
513
+ if (!__privateGet(this, _McpAppToolElement_instances, isPromoted_get)) {
514
+ return;
515
+ }
516
+ this._displayMode = "inline";
517
+ __privateMethod(this, _McpAppToolElement_instances, dispatchRequestDisplayMode_fn).call(this, "inline");
518
+ };
519
+ handleContainerKeydown_fn = function(evt) {
520
+ if (evt.key === "Escape" && __privateGet(this, _McpAppToolElement_instances, isPromoted_get)) {
521
+ evt.stopPropagation();
522
+ evt.preventDefault();
523
+ __privateMethod(this, _McpAppToolElement_instances, exitToInline_fn).call(this);
524
+ }
525
+ };
526
+ bordered_get = function() {
527
+ return __privateGet(this, _McpAppToolElement_instances, uiResource_get)?.prefersBorder !== false;
528
+ };
529
+ errorArtifact_get = function() {
530
+ return html`
531
+ <div class="container bordered">
532
+ <forge-ai-empty-state>
533
+ <svg slot="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="error-icon" aria-hidden="true">
534
+ <path fill="none" d="M0 0h24v24H0z" />
535
+ <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2m1 15h-2v-2h2zm0-4h-2V7h2z" />
536
+ </svg>
537
+ <h3 slot="heading">Unable to display app</h3>
538
+ <p slot="body">${__privateGet(this, _McpAppToolElement_instances, errorBody_get)}</p>
539
+ </forge-ai-empty-state>
540
+ </div>
541
+ `;
542
+ };
543
+ McpAppToolElement.styles = unsafeCSS(styles);
544
+ __decorateClass([
545
+ property({ attribute: false })
546
+ ], McpAppToolElement.prototype, "toolCall", 2);
547
+ __decorateClass([
548
+ property({ attribute: false })
549
+ ], McpAppToolElement.prototype, "toolDefinition", 2);
550
+ __decorateClass([
551
+ consume({ context: mcpAppHostContext, subscribe: true }),
552
+ property({ attribute: false })
553
+ ], McpAppToolElement.prototype, "host", 2);
554
+ __decorateClass([
555
+ query("iframe")
556
+ ], McpAppToolElement.prototype, "_iframe", 2);
557
+ __decorateClass([
558
+ query(".container")
559
+ ], McpAppToolElement.prototype, "_container", 2);
560
+ __decorateClass([
561
+ state()
562
+ ], McpAppToolElement.prototype, "_displayMode", 2);
563
+ __decorateClass([
564
+ state()
565
+ ], McpAppToolElement.prototype, "_lifecycle", 2);
566
+ __decorateClass([
567
+ state()
568
+ ], McpAppToolElement.prototype, "_pendingLink", 2);
569
+ McpAppToolElement = __decorateClass([
570
+ customElement("forge-ai-mcp-app")
571
+ ], McpAppToolElement);
572
+ export {
573
+ McpAppToolElement
574
+ };