@noodleseed/assistant 1.23.0 → 1.25.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.
- package/README.md +4 -9
- package/dist/{app-view-element-7ZQZLYbL.d.ts → app-view-element-9ojWWYov.d.cts} +3 -2
- package/dist/{app-view-element-1i_w6FDf.d.cts → app-view-element-BM4lral-.d.ts} +3 -2
- package/dist/app-view.cjs +213 -41
- package/dist/app-view.cjs.map +1 -1
- package/dist/app-view.d.cts +3 -3
- package/dist/app-view.d.ts +3 -3
- package/dist/app-view.js +2 -2
- package/dist/{appearance-Cc-eqSbp.d.cts → appearance-B6vSg8Ub.d.cts} +5 -0
- package/dist/{appearance-Cc-eqSbp.d.ts → appearance-B6vSg8Ub.d.ts} +5 -0
- package/dist/{chunk-IBDP6PXQ.js → chunk-7BQHW37I.js} +71 -3
- package/dist/chunk-7BQHW37I.js.map +1 -0
- package/dist/{chunk-5NBHHNI3.js → chunk-LNBUYHL7.js} +2 -2
- package/dist/chunk-LNBUYHL7.js.map +1 -0
- package/dist/{chunk-XKTUXFGX.js → chunk-P32MAR4K.js} +214 -42
- package/dist/chunk-P32MAR4K.js.map +1 -0
- package/dist/{chunk-X7UQDIGS.js → chunk-SGMECNNU.js} +94 -43
- package/dist/chunk-SGMECNNU.js.map +1 -0
- package/dist/{client-Bp_VKpMg.d.ts → client-BkogON2A.d.ts} +11 -1
- package/dist/{client-uo57Swlm.d.cts → client-C07ppTU_.d.cts} +11 -1
- package/dist/client.cjs +70 -2
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +2 -2
- package/dist/client.d.ts +2 -2
- package/dist/client.js +1 -1
- package/dist/embed.global.js +149 -114
- package/dist/index.cjs +396 -105
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/react/client.cjs +70 -2
- package/dist/react/client.cjs.map +1 -1
- package/dist/react/client.d.cts +2 -2
- package/dist/react/client.d.ts +2 -2
- package/dist/react/client.js +1 -1
- package/dist/react.cjs +396 -105
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +3 -3
- package/dist/react.d.ts +3 -3
- package/dist/react.js +4 -4
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +3 -1
- package/dist/server.d.ts +3 -1
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-5NBHHNI3.js.map +0 -1
- package/dist/chunk-IBDP6PXQ.js.map +0 -1
- package/dist/chunk-X7UQDIGS.js.map +0 -1
- package/dist/chunk-XKTUXFGX.js.map +0 -1
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
mountAssistantApp,
|
|
4
4
|
unmountAssistantApp,
|
|
5
5
|
updateAssistantAppTheme
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-P32MAR4K.js";
|
|
7
7
|
|
|
8
8
|
// src/app-view-element.ts
|
|
9
9
|
var APP_VIEW_TAG_NAME = "noodle-app-view";
|
|
@@ -177,4 +177,4 @@ export {
|
|
|
177
177
|
NoodleAppViewElement,
|
|
178
178
|
registerNoodleAppView
|
|
179
179
|
};
|
|
180
|
-
//# sourceMappingURL=chunk-
|
|
180
|
+
//# sourceMappingURL=chunk-LNBUYHL7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/app-view-element.ts","../src/app-view.ts"],"sourcesContent":["import { mountAssistantApp, unmountAssistantApp, updateAssistantAppTheme } from './app-host.js';\nimport { ASSISTANT_APP_VIEW_STYLES } from './app-view-styles.js';\nimport type { AssistantClient, AssistantViewAvailableDetail } from './client.js';\nimport type { AssistantErrorDetail } from './transport.js';\n\nexport const APP_VIEW_TAG_NAME = 'noodle-app-view';\n\nexport interface AssistantAppViewErrorDetail {\n readonly code: 'view_render_timeout' | 'view_bridge_error';\n readonly retryable: false;\n readonly stage: 'sandbox_load' | 'sandbox_proxy' | 'app_initialize';\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'noodle-app-view': NoodleAppViewElement;\n }\n\n interface HTMLElementEventMap {\n 'assistant-error': CustomEvent<AssistantErrorDetail>;\n }\n}\n\nconst HTMLElementBase: typeof HTMLElement =\n globalThis.HTMLElement ?? (class {} as unknown as typeof HTMLElement);\n\nfunction viewIdentity(view: AssistantViewAvailableDetail): string {\n return `${view.id}\\u0000${view.resourceUri}`;\n}\n\n/**\n * Framework-neutral host for one service-resolved MCP App view.\n *\n * `client` and `view` are object properties, not serialized attributes. Vue, Angular, and plain DOM\n * renderers can therefore pass the same `data-view` payload without taking a React dependency.\n */\nexport class NoodleAppViewElement extends HTMLElementBase {\n static readonly observedAttributes = ['allow-fullscreen', 'theme'];\n\n #allowFullscreen = false;\n #client: AssistantClient | undefined;\n #view: AssistantViewAvailableDetail | undefined;\n #theme: 'light' | 'dark' = 'light';\n #container: HTMLElement | undefined;\n #mounted: HTMLElement | undefined;\n #mountedClient: AssistantClient | undefined;\n #mountedAllowFullscreen = false;\n #mountedIdentity: string | undefined;\n #requestedTeardown: { readonly client: AssistantClient; readonly identity: string } | undefined;\n\n get client(): AssistantClient | undefined {\n return this.#client;\n }\n\n /** Allow the hosted App to request fullscreen. Disabled by default. */\n get allowFullscreen(): boolean {\n return this.#allowFullscreen;\n }\n\n set allowFullscreen(value: boolean) {\n const next = value === true;\n if (next === this.#allowFullscreen) return;\n this.#allowFullscreen = next;\n this.toggleAttribute('allow-fullscreen', next);\n this.#reconcile();\n }\n\n set client(value: AssistantClient | undefined) {\n if (value === this.#client) return;\n this.#client = value;\n this.#reconcile();\n }\n\n get view(): AssistantViewAvailableDetail | undefined {\n return this.#view;\n }\n\n set view(value: AssistantViewAvailableDetail | undefined) {\n this.#view = value;\n this.#reconcile();\n }\n\n get theme(): 'light' | 'dark' {\n return this.#theme;\n }\n\n set theme(value: 'light' | 'dark') {\n const next = value === 'dark' ? 'dark' : 'light';\n const changed = next !== this.#theme;\n this.#theme = next;\n if (this.getAttribute('data-theme') !== next) this.setAttribute('data-theme', next);\n if (changed && this.#mounted) updateAssistantAppTheme(this.#mounted, next);\n }\n\n connectedCallback(): void {\n this.#ensureContainer();\n this.#upgradeProperty('allowFullscreen');\n this.#upgradeProperty('client');\n this.#upgradeProperty('theme');\n this.#upgradeProperty('view');\n this.#reconcile();\n }\n\n disconnectedCallback(): void {\n this.#requestedTeardown = undefined;\n this.#releaseMount();\n }\n\n attributeChangedCallback(name: string, _previous: string | null, value: string | null): void {\n if (name === 'allow-fullscreen') this.allowFullscreen = value !== null;\n if (name === 'theme') this.theme = value === 'dark' ? 'dark' : 'light';\n }\n\n #ensureContainer(): HTMLElement {\n if (this.#container) return this.#container;\n const root = this.shadowRoot ?? this.attachShadow({ mode: 'open' });\n root.innerHTML = ASSISTANT_APP_VIEW_STYLES;\n const container = document.createElement('div');\n container.className = 'noodle-app-mount';\n container.setAttribute('part', 'mount');\n root.append(container);\n this.#container = container;\n return container;\n }\n\n #upgradeProperty(name: 'allowFullscreen' | 'client' | 'theme' | 'view'): void {\n const property = Object.getOwnPropertyDescriptor(this, name);\n if (!property) return;\n Reflect.deleteProperty(this, name);\n Reflect.set(this, name, property.value);\n }\n\n #releaseMount(): void {\n const mounted = this.#mounted;\n this.#mounted = undefined;\n this.#mountedClient = undefined;\n this.#mountedAllowFullscreen = false;\n this.#mountedIdentity = undefined;\n this.#container?.replaceChildren();\n if (mounted) void unmountAssistantApp(mounted);\n }\n\n #reconcile(): void {\n if (!this.isConnected) return;\n const client = this.#client;\n const detail = this.#view;\n const identity = detail ? viewIdentity(detail) : undefined;\n\n if (this.#mounted) {\n if (\n client === this.#mountedClient &&\n identity === this.#mountedIdentity &&\n this.#allowFullscreen === this.#mountedAllowFullscreen\n ) {\n return;\n }\n this.#releaseMount();\n }\n\n if (\n this.#requestedTeardown &&\n (client !== this.#requestedTeardown.client || identity !== this.#requestedTeardown.identity)\n ) {\n this.#requestedTeardown = undefined;\n }\n if (!client || !detail?.html || !identity || this.#requestedTeardown) return;\n\n const initialHtml = detail.html;\n const sandboxUrl = client.appSandboxUrl?.();\n let card: HTMLElement | undefined;\n card = mountAssistantApp(\n detail,\n {\n client,\n sendMessage: (message) => client.sendMessage(message),\n updateModelContext: (update) => client.updateModelContext(update),\n theme: this.#theme,\n },\n {\n allowFullscreen: this.#allowFullscreen,\n ...(sandboxUrl ? { sandboxUrl } : {}),\n getDetail: () => {\n const latest = this.#view;\n if (this.#client !== client || !latest || viewIdentity(latest) !== identity)\n return detail;\n return latest.html ? latest : { ...latest, html: initialHtml };\n },\n onRenderFailure: (failure) => {\n this.dispatchEvent(\n new CustomEvent<AssistantAppViewErrorDetail>('assistant-error', {\n detail: failure,\n bubbles: true,\n composed: true,\n }),\n );\n },\n onTeardownRequest: () => {\n if (this.#mounted !== card) return;\n this.#mounted = undefined;\n this.#mountedClient = undefined;\n this.#mountedIdentity = undefined;\n this.#requestedTeardown = { client, identity };\n },\n },\n );\n if (!card) return;\n this.#mounted = card;\n this.#mountedClient = client;\n this.#mountedAllowFullscreen = this.#allowFullscreen;\n this.#mountedIdentity = identity;\n this.#ensureContainer().replaceChildren(card);\n }\n}\n","import { APP_VIEW_TAG_NAME, NoodleAppViewElement } from './app-view-element.js';\n\nexport {\n APP_VIEW_TAG_NAME,\n type AssistantAppViewErrorDetail,\n NoodleAppViewElement,\n} from './app-view-element.js';\nexport type { AssistantClient, AssistantViewAvailableDetail } from './client.js';\n\n/** Register the framework-neutral MCP App host. Safe to call more than once or during SSR. */\nexport function registerNoodleAppView(): void {\n if (!globalThis.customElements?.get(APP_VIEW_TAG_NAME)) {\n globalThis.customElements?.define(APP_VIEW_TAG_NAME, NoodleAppViewElement);\n }\n}\n\nregisterNoodleAppView();\n"],"mappings":";;;;;;;;AAKO,IAAM,oBAAoB;AAkBjC,IAAM,kBACJ,WAAW,eAAgB,MAAM;AAAC;AAEpC,SAAS,aAAa,MAA4C;AAChE,SAAO,GAAG,KAAK,EAAE,KAAS,KAAK,WAAW;AAC5C;AAQO,IAAM,uBAAN,cAAmC,gBAAgB;AAAA,EACxD,OAAgB,qBAAqB,CAAC,oBAAoB,OAAO;AAAA,EAEjE,mBAAmB;AAAA,EACnB;AAAA,EACA;AAAA,EACA,SAA2B;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA,0BAA0B;AAAA,EAC1B;AAAA,EACA;AAAA,EAEA,IAAI,SAAsC;AACxC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,IAAI,kBAA2B;AAC7B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,gBAAgB,OAAgB;AAClC,UAAM,OAAO,UAAU;AACvB,QAAI,SAAS,KAAK,iBAAkB;AACpC,SAAK,mBAAmB;AACxB,SAAK,gBAAgB,oBAAoB,IAAI;AAC7C,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,IAAI,OAAO,OAAoC;AAC7C,QAAI,UAAU,KAAK,QAAS;AAC5B,SAAK,UAAU;AACf,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,IAAI,OAAiD;AACnD,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,KAAK,OAAiD;AACxD,SAAK,QAAQ;AACb,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,IAAI,QAA0B;AAC5B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,MAAM,OAAyB;AACjC,UAAM,OAAO,UAAU,SAAS,SAAS;AACzC,UAAM,UAAU,SAAS,KAAK;AAC9B,SAAK,SAAS;AACd,QAAI,KAAK,aAAa,YAAY,MAAM,KAAM,MAAK,aAAa,cAAc,IAAI;AAClF,QAAI,WAAW,KAAK,SAAU,yBAAwB,KAAK,UAAU,IAAI;AAAA,EAC3E;AAAA,EAEA,oBAA0B;AACxB,SAAK,iBAAiB;AACtB,SAAK,iBAAiB,iBAAiB;AACvC,SAAK,iBAAiB,QAAQ;AAC9B,SAAK,iBAAiB,OAAO;AAC7B,SAAK,iBAAiB,MAAM;AAC5B,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,uBAA6B;AAC3B,SAAK,qBAAqB;AAC1B,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,yBAAyB,MAAc,WAA0B,OAA4B;AAC3F,QAAI,SAAS,mBAAoB,MAAK,kBAAkB,UAAU;AAClE,QAAI,SAAS,QAAS,MAAK,QAAQ,UAAU,SAAS,SAAS;AAAA,EACjE;AAAA,EAEA,mBAAgC;AAC9B,QAAI,KAAK,WAAY,QAAO,KAAK;AACjC,UAAM,OAAO,KAAK,cAAc,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAClE,SAAK,YAAY;AACjB,UAAM,YAAY,SAAS,cAAc,KAAK;AAC9C,cAAU,YAAY;AACtB,cAAU,aAAa,QAAQ,OAAO;AACtC,SAAK,OAAO,SAAS;AACrB,SAAK,aAAa;AAClB,WAAO;AAAA,EACT;AAAA,EAEA,iBAAiB,MAA6D;AAC5E,UAAM,WAAW,OAAO,yBAAyB,MAAM,IAAI;AAC3D,QAAI,CAAC,SAAU;AACf,YAAQ,eAAe,MAAM,IAAI;AACjC,YAAQ,IAAI,MAAM,MAAM,SAAS,KAAK;AAAA,EACxC;AAAA,EAEA,gBAAsB;AACpB,UAAM,UAAU,KAAK;AACrB,SAAK,WAAW;AAChB,SAAK,iBAAiB;AACtB,SAAK,0BAA0B;AAC/B,SAAK,mBAAmB;AACxB,SAAK,YAAY,gBAAgB;AACjC,QAAI,QAAS,MAAK,oBAAoB,OAAO;AAAA,EAC/C;AAAA,EAEA,aAAmB;AACjB,QAAI,CAAC,KAAK,YAAa;AACvB,UAAM,SAAS,KAAK;AACpB,UAAM,SAAS,KAAK;AACpB,UAAM,WAAW,SAAS,aAAa,MAAM,IAAI;AAEjD,QAAI,KAAK,UAAU;AACjB,UACE,WAAW,KAAK,kBAChB,aAAa,KAAK,oBAClB,KAAK,qBAAqB,KAAK,yBAC/B;AACA;AAAA,MACF;AACA,WAAK,cAAc;AAAA,IACrB;AAEA,QACE,KAAK,uBACJ,WAAW,KAAK,mBAAmB,UAAU,aAAa,KAAK,mBAAmB,WACnF;AACA,WAAK,qBAAqB;AAAA,IAC5B;AACA,QAAI,CAAC,UAAU,CAAC,QAAQ,QAAQ,CAAC,YAAY,KAAK,mBAAoB;AAEtE,UAAM,cAAc,OAAO;AAC3B,UAAM,aAAa,OAAO,gBAAgB;AAC1C,QAAI;AACJ,WAAO;AAAA,MACL;AAAA,MACA;AAAA,QACE;AAAA,QACA,aAAa,CAAC,YAAY,OAAO,YAAY,OAAO;AAAA,QACpD,oBAAoB,CAAC,WAAW,OAAO,mBAAmB,MAAM;AAAA,QAChE,OAAO,KAAK;AAAA,MACd;AAAA,MACA;AAAA,QACE,iBAAiB,KAAK;AAAA,QACtB,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;AAAA,QACnC,WAAW,MAAM;AACf,gBAAM,SAAS,KAAK;AACpB,cAAI,KAAK,YAAY,UAAU,CAAC,UAAU,aAAa,MAAM,MAAM;AACjE,mBAAO;AACT,iBAAO,OAAO,OAAO,SAAS,EAAE,GAAG,QAAQ,MAAM,YAAY;AAAA,QAC/D;AAAA,QACA,iBAAiB,CAAC,YAAY;AAC5B,eAAK;AAAA,YACH,IAAI,YAAyC,mBAAmB;AAAA,cAC9D,QAAQ;AAAA,cACR,SAAS;AAAA,cACT,UAAU;AAAA,YACZ,CAAC;AAAA,UACH;AAAA,QACF;AAAA,QACA,mBAAmB,MAAM;AACvB,cAAI,KAAK,aAAa,KAAM;AAC5B,eAAK,WAAW;AAChB,eAAK,iBAAiB;AACtB,eAAK,mBAAmB;AACxB,eAAK,qBAAqB,EAAE,QAAQ,SAAS;AAAA,QAC/C;AAAA,MACF;AAAA,IACF;AACA,QAAI,CAAC,KAAM;AACX,SAAK,WAAW;AAChB,SAAK,iBAAiB;AACtB,SAAK,0BAA0B,KAAK;AACpC,SAAK,mBAAmB;AACxB,SAAK,iBAAiB,EAAE,gBAAgB,IAAI;AAAA,EAC9C;AACF;;;AC1MO,SAAS,wBAA8B;AAC5C,MAAI,CAAC,WAAW,gBAAgB,IAAI,iBAAiB,GAAG;AACtD,eAAW,gBAAgB,OAAO,mBAAmB,oBAAoB;AAAA,EAC3E;AACF;AAEA,sBAAsB;","names":[]}
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
__require
|
|
25
25
|
} from "./chunk-5FUTL2UF.js";
|
|
26
26
|
|
|
27
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.4.3/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
|
|
27
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_supports-color@7.2.0_zod@4.4.3/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
|
|
28
28
|
var RELATED_TASK_META_KEY = "io.modelcontextprotocol/related-task";
|
|
29
29
|
var JSONRPC_VERSION = "2.0";
|
|
30
30
|
var AssertObjectSchema = custom((v2) => v2 !== null && (typeof v2 === "object" || typeof v2 === "function"));
|
|
@@ -1541,7 +1541,7 @@ var UrlElicitationRequiredError = class extends McpError {
|
|
|
1541
1541
|
}
|
|
1542
1542
|
};
|
|
1543
1543
|
|
|
1544
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.4.3/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
|
|
1544
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_supports-color@7.2.0_zod@4.4.3/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
|
|
1545
1545
|
function isZ4Schema(s2) {
|
|
1546
1546
|
const schema = s2;
|
|
1547
1547
|
return !!schema._zod;
|
|
@@ -1604,7 +1604,7 @@ function getLiteralValue(schema) {
|
|
|
1604
1604
|
return void 0;
|
|
1605
1605
|
}
|
|
1606
1606
|
|
|
1607
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.4.3/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
|
|
1607
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_supports-color@7.2.0_zod@4.4.3/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
|
|
1608
1608
|
function isTerminal(status) {
|
|
1609
1609
|
return status === "completed" || status === "failed" || status === "cancelled";
|
|
1610
1610
|
}
|
|
@@ -1612,7 +1612,7 @@ function isTerminal(status) {
|
|
|
1612
1612
|
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.4.3/node_modules/zod-to-json-schema/dist/esm/parsers/string.js
|
|
1613
1613
|
var ALPHA_NUMERIC = new Set("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789");
|
|
1614
1614
|
|
|
1615
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.4.3/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js
|
|
1615
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_supports-color@7.2.0_zod@4.4.3/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js
|
|
1616
1616
|
function getMethodLiteral(schema) {
|
|
1617
1617
|
const shape = getObjectShape(schema);
|
|
1618
1618
|
const methodSchema = shape?.method;
|
|
@@ -1633,7 +1633,7 @@ function parseWithCompat(schema, data) {
|
|
|
1633
1633
|
return result.data;
|
|
1634
1634
|
}
|
|
1635
1635
|
|
|
1636
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.4.3/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
|
|
1636
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_supports-color@7.2.0_zod@4.4.3/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
|
|
1637
1637
|
var DEFAULT_REQUEST_TIMEOUT_MSEC = 6e4;
|
|
1638
1638
|
var Protocol = class {
|
|
1639
1639
|
constructor(_options) {
|
|
@@ -2744,6 +2744,15 @@ var E = class {
|
|
|
2744
2744
|
sessionId;
|
|
2745
2745
|
setProtocolVersion;
|
|
2746
2746
|
};
|
|
2747
|
+
function AZ(X) {
|
|
2748
|
+
if (!X) return "";
|
|
2749
|
+
let Y = [];
|
|
2750
|
+
if (X.camera) Y.push("camera");
|
|
2751
|
+
if (X.microphone) Y.push("microphone");
|
|
2752
|
+
if (X.geolocation) Y.push("geolocation");
|
|
2753
|
+
if (X.clipboardWrite) Y.push("clipboard-write");
|
|
2754
|
+
return Y.join("; ");
|
|
2755
|
+
}
|
|
2747
2756
|
var KX = [j];
|
|
2748
2757
|
var DX = class extends _ {
|
|
2749
2758
|
_client;
|
|
@@ -3014,34 +3023,131 @@ function GX(X, Y) {
|
|
|
3014
3023
|
return JSON.stringify(X) === JSON.stringify(Y);
|
|
3015
3024
|
}
|
|
3016
3025
|
|
|
3026
|
+
// src/app-sandbox-policy.ts
|
|
3027
|
+
var MAX_DOMAINS_PER_DIRECTIVE = 32;
|
|
3028
|
+
function isRecord(value) {
|
|
3029
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3030
|
+
}
|
|
3031
|
+
function isLoopback(hostname) {
|
|
3032
|
+
return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "[::1]";
|
|
3033
|
+
}
|
|
3034
|
+
function normalizeDomain(value, connect) {
|
|
3035
|
+
if (value.length > 512 || /[;\r\n'"\s]/u.test(value)) return void 0;
|
|
3036
|
+
try {
|
|
3037
|
+
const parsed = new URL(value);
|
|
3038
|
+
const secure = parsed.protocol === "https:" || connect && parsed.protocol === "wss:";
|
|
3039
|
+
const local = isLoopback(parsed.hostname) && (parsed.protocol === "http:" || connect && parsed.protocol === "ws:");
|
|
3040
|
+
if (!secure && !local) return void 0;
|
|
3041
|
+
if (parsed.username || parsed.password || parsed.pathname !== "/" || parsed.search || parsed.hash) {
|
|
3042
|
+
return void 0;
|
|
3043
|
+
}
|
|
3044
|
+
return parsed.origin;
|
|
3045
|
+
} catch {
|
|
3046
|
+
return void 0;
|
|
3047
|
+
}
|
|
3048
|
+
}
|
|
3049
|
+
function normalizeDomains(values, connect) {
|
|
3050
|
+
const normalized = [
|
|
3051
|
+
...new Set(
|
|
3052
|
+
values.slice(0, MAX_DOMAINS_PER_DIRECTIVE).map((value) => typeof value === "string" ? normalizeDomain(value, connect) : void 0).filter((value) => value !== void 0)
|
|
3053
|
+
)
|
|
3054
|
+
];
|
|
3055
|
+
return normalized;
|
|
3056
|
+
}
|
|
3057
|
+
function resolveAssistantAppSandboxPolicy(resourceMeta) {
|
|
3058
|
+
if (!isRecord(resourceMeta)) return {};
|
|
3059
|
+
const rawCsp = resourceMeta.csp;
|
|
3060
|
+
const csp = isRecord(rawCsp) ? {
|
|
3061
|
+
...Array.isArray(rawCsp.connectDomains) ? { connectDomains: normalizeDomains(rawCsp.connectDomains, true) } : {},
|
|
3062
|
+
...Array.isArray(rawCsp.resourceDomains) ? { resourceDomains: normalizeDomains(rawCsp.resourceDomains, false) } : {},
|
|
3063
|
+
...Array.isArray(rawCsp.frameDomains) ? { frameDomains: normalizeDomains(rawCsp.frameDomains, false) } : {},
|
|
3064
|
+
...Array.isArray(rawCsp.baseUriDomains) ? { baseUriDomains: normalizeDomains(rawCsp.baseUriDomains, false) } : {}
|
|
3065
|
+
} : void 0;
|
|
3066
|
+
const rawPermissions = resourceMeta.permissions;
|
|
3067
|
+
const permissions = isRecord(rawPermissions) ? {
|
|
3068
|
+
...isRecord(rawPermissions.camera) ? { camera: {} } : {},
|
|
3069
|
+
...isRecord(rawPermissions.microphone) ? { microphone: {} } : {},
|
|
3070
|
+
...isRecord(rawPermissions.geolocation) ? { geolocation: {} } : {},
|
|
3071
|
+
...isRecord(rawPermissions.clipboardWrite) ? { clipboardWrite: {} } : {}
|
|
3072
|
+
} : void 0;
|
|
3073
|
+
const allowAttribute = AZ(permissions);
|
|
3074
|
+
return {
|
|
3075
|
+
...csp === void 0 ? {} : { csp },
|
|
3076
|
+
...permissions === void 0 ? {} : { permissions },
|
|
3077
|
+
...allowAttribute ? { allowAttribute } : {}
|
|
3078
|
+
};
|
|
3079
|
+
}
|
|
3080
|
+
function assistantAppSandboxUrl(sandboxUrl, policy) {
|
|
3081
|
+
const parsed = new URL(sandboxUrl);
|
|
3082
|
+
if (policy.csp) parsed.searchParams.set("csp", JSON.stringify(policy.csp));
|
|
3083
|
+
const parentOrigin = globalThis.location?.origin;
|
|
3084
|
+
if (parentOrigin && parentOrigin !== "null") {
|
|
3085
|
+
parsed.hash = new URLSearchParams({ parentOrigin }).toString();
|
|
3086
|
+
}
|
|
3087
|
+
return parsed.href;
|
|
3088
|
+
}
|
|
3089
|
+
|
|
3017
3090
|
// src/app-host.ts
|
|
3018
|
-
var PROXY_DOCUMENT = `<!doctype html><meta charset="utf-8"><style>html,body,iframe{border:0;margin:0;width:100%;height:100%;overflow:hidden}body{background:transparent}</style><script>
|
|
3019
|
-
let inner;
|
|
3091
|
+
var PROXY_DOCUMENT = `<!doctype html><meta charset="utf-8"><style>html,body,iframe{border:0;margin:0;width:100%;height:100%;overflow:hidden}body{background:transparent}</style><body><script>
|
|
3092
|
+
let inner,loaded=false;
|
|
3093
|
+
if(self===top)throw new Error('The assistant sandbox relay must be embedded');
|
|
3094
|
+
const standardSandbox='allow-scripts allow-same-origin allow-forms';
|
|
3095
|
+
const rawParentOrigin=new URLSearchParams(location.hash.slice(1)).get('parentOrigin');
|
|
3096
|
+
let expectedParentOrigin;
|
|
3097
|
+
try{const parsed=new URL(rawParentOrigin||'');if(parsed.origin===rawParentOrigin&&/^https?:$/.test(parsed.protocol))expectedParentOrigin=parsed.origin}catch{}
|
|
3098
|
+
const parentTarget=expectedParentOrigin||'*';
|
|
3099
|
+
const ownOrigin=self.origin;
|
|
3020
3100
|
const ready={jsonrpc:'2.0',method:'ui/notifications/sandbox-proxy-ready',params:{}};
|
|
3021
3101
|
// Re-announce until the host acknowledges with the resource: when this document is hosted
|
|
3022
3102
|
// cross-origin, the first announcement can arrive before the host's load handler is listening.
|
|
3023
|
-
const announce=setInterval(()=>parent.postMessage(ready,
|
|
3103
|
+
const announce=setInterval(()=>parent.postMessage(ready,parentTarget),120);
|
|
3024
3104
|
setTimeout(()=>clearInterval(announce),15000);
|
|
3025
3105
|
addEventListener('message',(event)=>{
|
|
3026
3106
|
if(event.source===parent){
|
|
3107
|
+
if(expectedParentOrigin&&event.origin!==expectedParentOrigin)return;
|
|
3027
3108
|
const message=event.data;
|
|
3028
3109
|
if(message?.method==='ui/notifications/sandbox-resource-ready'){
|
|
3029
3110
|
clearInterval(announce);
|
|
3030
|
-
if(
|
|
3111
|
+
if(loaded)return;
|
|
3112
|
+
loaded=true;
|
|
3113
|
+
const requestedSandbox=message.params?.sandbox;
|
|
3031
3114
|
inner=document.createElement('iframe');
|
|
3032
|
-
inner.setAttribute('sandbox',
|
|
3115
|
+
inner.setAttribute('sandbox',requestedSandbox===standardSandbox?standardSandbox:'allow-scripts');
|
|
3033
3116
|
inner.setAttribute('referrerpolicy','no-referrer');
|
|
3034
|
-
|
|
3035
|
-
|
|
3117
|
+
const permissions=message.params?.permissions;
|
|
3118
|
+
const allow=[];
|
|
3119
|
+
if(permissions?.camera)allow.push('camera');
|
|
3120
|
+
if(permissions?.microphone)allow.push('microphone');
|
|
3121
|
+
if(permissions?.geolocation)allow.push('geolocation');
|
|
3122
|
+
if(permissions?.clipboardWrite)allow.push('clipboard-write');
|
|
3123
|
+
if(allow.length)inner.setAttribute('allow',allow.join('; '));
|
|
3124
|
+
document.body.append(inner);
|
|
3125
|
+
let html=String(message.params?.html||'');
|
|
3126
|
+
const csp=message.params?.csp;
|
|
3127
|
+
if(csp&&typeof csp==='object'){
|
|
3128
|
+
const list=(value,fallback)=>Array.isArray(value)&&value.length?value.join(' '):fallback;
|
|
3129
|
+
const resources=Array.isArray(csp.resourceDomains)?csp.resourceDomains:[];
|
|
3130
|
+
const suffix=resources.length?' '+resources.join(' '):'';
|
|
3131
|
+
const policy=["default-src 'none'","script-src 'unsafe-inline'"+suffix,"style-src 'unsafe-inline'"+suffix,'img-src data: blob:'+suffix,'font-src data: blob:'+suffix,'media-src data: blob:'+suffix,'worker-src blob:'+suffix,'connect-src '+list(csp.connectDomains,"'none'"),'frame-src '+list(csp.frameDomains,"'none'"),"object-src 'none'","form-action 'none'",'base-uri '+list(csp.baseUriDomains,"'none'")].join('; ');
|
|
3132
|
+
const meta='<meta http-equiv="Content-Security-Policy" content="'+policy.replace(/&/g,'&').replace(/"/g,'"')+'">';
|
|
3133
|
+
const doctype=html.match(/^\\s*<!doctype[^>]*>/i);
|
|
3134
|
+
html=doctype?html.slice(0,doctype[0].length)+meta+html.slice(doctype[0].length):meta+html;
|
|
3135
|
+
}
|
|
3136
|
+
try{
|
|
3137
|
+
const doc=inner.contentDocument||inner.contentWindow?.document;
|
|
3138
|
+
if(!doc)throw new Error('document unavailable');
|
|
3139
|
+
doc.open();doc.write(html);doc.close();
|
|
3140
|
+
}catch{inner.srcdoc=html}
|
|
3036
3141
|
return;
|
|
3037
3142
|
}
|
|
3038
3143
|
inner?.contentWindow?.postMessage(message,'*');
|
|
3039
3144
|
} else if(inner && event.source===inner.contentWindow) {
|
|
3040
|
-
|
|
3145
|
+
if(event.origin!==ownOrigin)return;
|
|
3146
|
+
parent.postMessage(event.data,parentTarget);
|
|
3041
3147
|
}
|
|
3042
3148
|
});
|
|
3043
|
-
parent.postMessage(ready,
|
|
3044
|
-
</script>`;
|
|
3149
|
+
parent.postMessage(ready,parentTarget);
|
|
3150
|
+
</script></body>`;
|
|
3045
3151
|
function isAllowedAppLink(value, allowedDomains, baseUrl) {
|
|
3046
3152
|
try {
|
|
3047
3153
|
const parsed = new URL(value, baseUrl);
|
|
@@ -3068,16 +3174,42 @@ function createAssistantAppHostContext(theme, allowFullscreen = false, displayMo
|
|
|
3068
3174
|
}
|
|
3069
3175
|
var APP_RENDER_TIMEOUT_MS = 1e4;
|
|
3070
3176
|
var APP_TEARDOWN_TIMEOUT_MS = 1e3;
|
|
3177
|
+
var STANDARD_SANDBOX = "allow-scripts allow-same-origin allow-forms";
|
|
3071
3178
|
var mountedApps = /* @__PURE__ */ new WeakMap();
|
|
3072
3179
|
function resolveSandboxUrl(value) {
|
|
3073
3180
|
if (!value) return void 0;
|
|
3074
3181
|
try {
|
|
3075
3182
|
const parsed = new URL(value);
|
|
3076
|
-
|
|
3183
|
+
const loopback = parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1" || parsed.hostname === "[::1]";
|
|
3184
|
+
const permittedProtocol = parsed.protocol === "https:" || parsed.protocol === "http:" && loopback;
|
|
3185
|
+
const embedderOrigin = globalThis.location?.origin;
|
|
3186
|
+
if (!permittedProtocol || embedderOrigin && embedderOrigin !== "null" && parsed.origin === embedderOrigin) {
|
|
3187
|
+
return void 0;
|
|
3188
|
+
}
|
|
3189
|
+
return parsed.href;
|
|
3077
3190
|
} catch {
|
|
3078
3191
|
return void 0;
|
|
3079
3192
|
}
|
|
3080
3193
|
}
|
|
3194
|
+
function copyAppJson(value, depth = 0) {
|
|
3195
|
+
if (depth > 64) throw new Error("App payload nesting exceeds the host limit");
|
|
3196
|
+
if (value === null || typeof value === "string" || typeof value === "boolean") return value;
|
|
3197
|
+
if (typeof value === "number") {
|
|
3198
|
+
if (!Number.isFinite(value)) throw new Error("App payload numbers must be finite");
|
|
3199
|
+
return value;
|
|
3200
|
+
}
|
|
3201
|
+
if (Array.isArray(value)) return value.map((entry) => copyAppJson(entry, depth + 1));
|
|
3202
|
+
const copied = {};
|
|
3203
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
3204
|
+
Object.defineProperty(copied, key, {
|
|
3205
|
+
value: copyAppJson(entry, depth + 1),
|
|
3206
|
+
enumerable: true,
|
|
3207
|
+
configurable: true,
|
|
3208
|
+
writable: true
|
|
3209
|
+
});
|
|
3210
|
+
}
|
|
3211
|
+
return copied;
|
|
3212
|
+
}
|
|
3081
3213
|
function mountAssistantApp(detail, actions, options = {}) {
|
|
3082
3214
|
if (!detail.html) return void 0;
|
|
3083
3215
|
const card = document.createElement("section");
|
|
@@ -3098,16 +3230,25 @@ function mountAssistantApp(detail, actions, options = {}) {
|
|
|
3098
3230
|
const frame = document.createElement("iframe");
|
|
3099
3231
|
frame.className = "noodle-app-frame";
|
|
3100
3232
|
frame.title = detail.title ?? detail.tool;
|
|
3101
|
-
|
|
3233
|
+
const policy = resolveAssistantAppSandboxPolicy(detail.resourceMeta);
|
|
3102
3234
|
frame.setAttribute("referrerpolicy", "no-referrer");
|
|
3103
3235
|
const sandboxUrl = resolveSandboxUrl(options.sandboxUrl);
|
|
3104
|
-
|
|
3105
|
-
|
|
3236
|
+
const appliedPolicy = sandboxUrl ? policy : { csp: policy.csp ?? {} };
|
|
3237
|
+
if (sandboxUrl) {
|
|
3238
|
+
frame.setAttribute("sandbox", STANDARD_SANDBOX);
|
|
3239
|
+
if (policy.allowAttribute) frame.setAttribute("allow", policy.allowAttribute);
|
|
3240
|
+
frame.src = assistantAppSandboxUrl(sandboxUrl, policy);
|
|
3241
|
+
} else {
|
|
3242
|
+
frame.setAttribute("sandbox", "allow-scripts");
|
|
3243
|
+
frame.srcdoc = PROXY_DOCUMENT;
|
|
3244
|
+
}
|
|
3106
3245
|
card.append(frame);
|
|
3107
3246
|
let mountedBridge;
|
|
3108
3247
|
let mountedTransport;
|
|
3109
3248
|
let destroyed = false;
|
|
3110
3249
|
let initialized = false;
|
|
3250
|
+
let renderFailed = false;
|
|
3251
|
+
let renderStage = "sandbox_load";
|
|
3111
3252
|
let currentTheme = actions.theme;
|
|
3112
3253
|
let displayMode = "inline";
|
|
3113
3254
|
let hostContext = createAssistantAppHostContext(
|
|
@@ -3116,6 +3257,15 @@ function mountAssistantApp(detail, actions, options = {}) {
|
|
|
3116
3257
|
displayMode
|
|
3117
3258
|
);
|
|
3118
3259
|
let destroyPromise;
|
|
3260
|
+
let transportClosePromise;
|
|
3261
|
+
let renderTimer;
|
|
3262
|
+
const closeTransport = () => {
|
|
3263
|
+
if (transportClosePromise) return transportClosePromise;
|
|
3264
|
+
const closing = mountedTransport?.close().catch(() => {
|
|
3265
|
+
}) ?? Promise.resolve();
|
|
3266
|
+
transportClosePromise = closing;
|
|
3267
|
+
return closing;
|
|
3268
|
+
};
|
|
3119
3269
|
const applyDisplayMode = (requestedMode) => {
|
|
3120
3270
|
displayMode = requestedMode === "fullscreen" && options.allowFullscreen === true ? "fullscreen" : "inline";
|
|
3121
3271
|
card.toggleAttribute("data-fullscreen", displayMode === "fullscreen");
|
|
@@ -3133,18 +3283,26 @@ function mountAssistantApp(detail, actions, options = {}) {
|
|
|
3133
3283
|
applyDisplayMode("inline");
|
|
3134
3284
|
frame.focus();
|
|
3135
3285
|
});
|
|
3136
|
-
const
|
|
3137
|
-
if (initialized || !frame.isConnected)
|
|
3286
|
+
const showRenderFailure = (code) => {
|
|
3287
|
+
if (code === "view_render_timeout" && initialized || destroyed || renderFailed || !frame.isConnected)
|
|
3288
|
+
return;
|
|
3289
|
+
renderFailed = true;
|
|
3290
|
+
clearTimeout(renderTimer);
|
|
3138
3291
|
const note = document.createElement("div");
|
|
3139
3292
|
note.className = "noodle-app-fallback";
|
|
3140
3293
|
note.textContent = "This app view could not be displayed.";
|
|
3141
3294
|
frame.replaceWith(note);
|
|
3142
|
-
options.onRenderFailure?.({ code
|
|
3295
|
+
options.onRenderFailure?.({ code, retryable: false, stage: renderStage });
|
|
3296
|
+
void closeTransport();
|
|
3297
|
+
};
|
|
3298
|
+
renderTimer = setTimeout(() => {
|
|
3299
|
+
showRenderFailure("view_render_timeout");
|
|
3143
3300
|
}, APP_RENDER_TIMEOUT_MS);
|
|
3144
3301
|
frame.addEventListener(
|
|
3145
3302
|
"load",
|
|
3146
3303
|
() => {
|
|
3147
|
-
if (destroyed) return;
|
|
3304
|
+
if (destroyed || renderFailed) return;
|
|
3305
|
+
renderStage = "sandbox_proxy";
|
|
3148
3306
|
const target = frame.contentWindow;
|
|
3149
3307
|
if (!target) return;
|
|
3150
3308
|
const bridge = new DX(
|
|
@@ -3155,7 +3313,11 @@ function mountAssistantApp(detail, actions, options = {}) {
|
|
|
3155
3313
|
serverTools: {},
|
|
3156
3314
|
serverResources: {},
|
|
3157
3315
|
updateModelContext: { text: {}, structuredContent: {} },
|
|
3158
|
-
message: { text: {} }
|
|
3316
|
+
message: { text: {} },
|
|
3317
|
+
sandbox: {
|
|
3318
|
+
...appliedPolicy.csp === void 0 ? {} : { csp: appliedPolicy.csp },
|
|
3319
|
+
...appliedPolicy.permissions === void 0 ? {} : { permissions: appliedPolicy.permissions }
|
|
3320
|
+
}
|
|
3159
3321
|
},
|
|
3160
3322
|
{
|
|
3161
3323
|
hostContext
|
|
@@ -3163,13 +3325,15 @@ function mountAssistantApp(detail, actions, options = {}) {
|
|
|
3163
3325
|
);
|
|
3164
3326
|
mountedBridge = bridge;
|
|
3165
3327
|
bridge.onsandboxready = () => {
|
|
3166
|
-
if (destroyed) return;
|
|
3328
|
+
if (destroyed || renderFailed) return;
|
|
3329
|
+
renderStage = "app_initialize";
|
|
3167
3330
|
const current = options.getDetail?.() ?? detail;
|
|
3168
3331
|
void bridge.sendSandboxResourceReady({
|
|
3169
3332
|
html: current.html,
|
|
3170
|
-
sandbox: "allow-scripts",
|
|
3171
|
-
...
|
|
3172
|
-
|
|
3333
|
+
sandbox: sandboxUrl ? STANDARD_SANDBOX : "allow-scripts",
|
|
3334
|
+
...appliedPolicy.csp === void 0 ? {} : { csp: appliedPolicy.csp },
|
|
3335
|
+
...appliedPolicy.permissions === void 0 ? {} : { permissions: appliedPolicy.permissions }
|
|
3336
|
+
}).catch(() => showRenderFailure("view_bridge_error"));
|
|
3173
3337
|
};
|
|
3174
3338
|
bridge.onsizechange = ({ height }) => {
|
|
3175
3339
|
if (destroyed) return;
|
|
@@ -3233,21 +3397,30 @@ function mountAssistantApp(detail, actions, options = {}) {
|
|
|
3233
3397
|
return await actions.client.requestApp("resources/read", params);
|
|
3234
3398
|
};
|
|
3235
3399
|
bridge.oninitialized = () => {
|
|
3236
|
-
if (destroyed) return;
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3400
|
+
if (destroyed || renderFailed) return;
|
|
3401
|
+
try {
|
|
3402
|
+
const current = options.getDetail?.() ?? detail;
|
|
3403
|
+
const copiedArguments = copyAppJson(current.arguments ?? {});
|
|
3404
|
+
const copiedResult = copyAppJson(current.result);
|
|
3405
|
+
const argumentsRecord = typeof copiedArguments === "object" && copiedArguments !== null && !Array.isArray(copiedArguments) ? copiedArguments : {};
|
|
3406
|
+
initialized = true;
|
|
3407
|
+
clearTimeout(renderTimer);
|
|
3408
|
+
bridge.setHostContext(hostContext);
|
|
3409
|
+
void Promise.all([
|
|
3410
|
+
bridge.sendToolInput({ arguments: argumentsRecord }),
|
|
3411
|
+
bridge.sendToolResult({
|
|
3412
|
+
content: [{ type: "text", text: JSON.stringify(copiedResult) }],
|
|
3413
|
+
...typeof copiedResult === "object" && copiedResult !== null && !Array.isArray(copiedResult) ? { structuredContent: copiedResult } : {}
|
|
3414
|
+
})
|
|
3415
|
+
]).catch(() => showRenderFailure("view_bridge_error"));
|
|
3416
|
+
} catch {
|
|
3417
|
+
showRenderFailure("view_bridge_error");
|
|
3418
|
+
}
|
|
3246
3419
|
};
|
|
3247
3420
|
const transport = new E(target, target);
|
|
3248
3421
|
mountedTransport = transport;
|
|
3249
3422
|
void bridge.connect(transport).catch(() => {
|
|
3250
|
-
|
|
3423
|
+
showRenderFailure("view_bridge_error");
|
|
3251
3424
|
});
|
|
3252
3425
|
},
|
|
3253
3426
|
{ once: true }
|
|
@@ -3273,8 +3446,7 @@ function mountAssistantApp(detail, actions, options = {}) {
|
|
|
3273
3446
|
}
|
|
3274
3447
|
} catch {
|
|
3275
3448
|
}
|
|
3276
|
-
await
|
|
3277
|
-
});
|
|
3449
|
+
await closeTransport();
|
|
3278
3450
|
card.remove();
|
|
3279
3451
|
mountedApps.delete(card);
|
|
3280
3452
|
})();
|
|
@@ -3320,4 +3492,4 @@ export {
|
|
|
3320
3492
|
ASSISTANT_APP_VIEW_CSS,
|
|
3321
3493
|
ASSISTANT_APP_VIEW_STYLES
|
|
3322
3494
|
};
|
|
3323
|
-
//# sourceMappingURL=chunk-
|
|
3495
|
+
//# sourceMappingURL=chunk-P32MAR4K.js.map
|