Files
SnowLuma/.pnpm-store/v11/files/6e/e74c38c174bbc38a1b05d775609fc03722555d6c7c06a4d86ad1b4dab47548363e1a753db21ea5dbbd7740a3c297ccf94320ff8cc6e7ae72719d9fcab0af43
T
TanTan 2a69b23b47
Dev Build / cleanup (push) Canceled after 0s
Dev Build / typecheck (push) Canceled after 0s
Dev Build / build (linux-arm64, ubuntu-24.04-arm, linux-arm64) (push) Canceled after 0s
Dev Build / build (linux-x64, ubuntu-latest, linux-x64) (push) Canceled after 0s
Dev Build / build (win-x64, windows-latest, win32-x64) (push) Canceled after 0s
Dev Build / dispatch-dev-docker (push) Canceled after 0s
docs: 仓库链接指向本镜像仓库
2026-11-13 09:27:07 +08:00

40 lines
33 KiB
Plaintext

import{Protocol as UF}from"@modelcontextprotocol/client";import{EmptyResultSchema as qF,LoggingMessageNotificationSchema as yF}from"@modelcontextprotocol/core";class D{_eventSlots=new Map;setHandler(G,Q){let W=this._ensureEventSlot(G);if(W.onHandler&&Q)console.warn(`[MCP Apps] on${String(G)} handler replaced. Use addEventListener("${String(G)}", …) to add multiple listeners without replacing.`);W.onHandler=Q}getHandler(G){return this._eventSlots.get(G)?.onHandler}addEventListener(G,Q){this._ensureEventSlot(G).listeners.push(Q)}removeEventListener(G,Q){let W=this._eventSlots.get(G);if(!W)return;let X=W.listeners.indexOf(Q);if(X!==-1)W.listeners.splice(X,1)}dispatch(G,Q){let W=this._eventSlots.get(G);if(!W)return;W.onHandler?.(Q);for(let X of[...W.listeners])X(Q)}_ensureEventSlot(G){let Q=this._eventSlots.get(G);if(!Q)Q={listeners:[]},this._eventSlots.set(G,Q);return Q}}class O{_methods=new Set;claim(G,Q){if(this._methods.has(G))throw Error(`Handler for "${G}" already registered (via ${Q}). Use addEventListener() to attach multiple listeners, or the on* setter for replace semantics.`);this._methods.add(G)}replace(G){this._methods.add(G)}release(G){this._methods.delete(G)}has(G){return this._methods.has(G)}}var b=new Set;function E(G,Q){let[W,X]=Q,Y=W?.shape;if(typeof Y?.method?.value!=="string")return;let Z=Y.method.value,z=G==="request"?"setRequestHandler":"setNotificationHandler";if(!b.has(z))b.add(z),console.warn(`[ext-apps] ${z}(Schema, handler) is deprecated; use ${z}("${Z}", { params: Schema.shape.params }, handler).`);let k=X;return[Z,{params:Y.params},G==="request"?(B,o)=>k({method:Z,params:B},l(o)):(B)=>k({method:Z,params:B})]}function l(G){return{signal:G.mcpReq.signal,requestId:G.mcpReq.id,sessionId:G.sessionId,_meta:G.mcpReq._meta,sendRequest:G.mcpReq.send,sendNotification:G.mcpReq.notify,authInfo:G.http?.authInfo}}var J="2026-01-26",r="ui/open-link",s="ui/download-file",t="ui/message",a="ui/notifications/sandbox-proxy-ready",e="ui/notifications/sandbox-resource-ready",FF="ui/notifications/size-changed",GF="ui/notifications/tool-input",H="ui/notifications/tool-input-partial",QF="ui/notifications/tool-result",WF="ui/notifications/tool-cancelled",XF="ui/notifications/host-context-changed",YF="ui/notifications/request-teardown",ZF="ui/resource-teardown",$F="ui/initialize",zF="ui/notifications/initialized",JF="ui/request-display-mode";import{z as F}from"zod/v4";import{ContentBlockSchema as x,CallToolResultSchema as KF,EmbeddedResourceSchema as NF,ImplementationSchema as v,RequestIdSchema as jF,ResourceLinkSchema as _F,ToolSchema as BF}from"@modelcontextprotocol/core";var d=F.union([F.literal("light"),F.literal("dark")]).describe("Color theme preference for the host environment."),$=F.union([F.literal("inline"),F.literal("fullscreen"),F.literal("pip")]).describe("Display mode for UI presentation."),DF=F.union([F.literal("--color-background-primary"),F.literal("--color-background-secondary"),F.literal("--color-background-tertiary"),F.literal("--color-background-inverse"),F.literal("--color-background-ghost"),F.literal("--color-background-info"),F.literal("--color-background-danger"),F.literal("--color-background-success"),F.literal("--color-background-warning"),F.literal("--color-background-disabled"),F.literal("--color-text-primary"),F.literal("--color-text-secondary"),F.literal("--color-text-tertiary"),F.literal("--color-text-inverse"),F.literal("--color-text-ghost"),F.literal("--color-text-info"),F.literal("--color-text-danger"),F.literal("--color-text-success"),F.literal("--color-text-warning"),F.literal("--color-text-disabled"),F.literal("--color-border-primary"),F.literal("--color-border-secondary"),F.literal("--color-border-tertiary"),F.literal("--color-border-inverse"),F.literal("--color-border-ghost"),F.literal("--color-border-info"),F.literal("--color-border-danger"),F.literal("--color-border-success"),F.literal("--color-border-warning"),F.literal("--color-border-disabled"),F.literal("--color-ring-primary"),F.literal("--color-ring-secondary"),F.literal("--color-ring-inverse"),F.literal("--color-ring-info"),F.literal("--color-ring-danger"),F.literal("--color-ring-success"),F.literal("--color-ring-warning"),F.literal("--font-sans"),F.literal("--font-mono"),F.literal("--font-weight-normal"),F.literal("--font-weight-medium"),F.literal("--font-weight-semibold"),F.literal("--font-weight-bold"),F.literal("--font-text-xs-size"),F.literal("--font-text-sm-size"),F.literal("--font-text-md-size"),F.literal("--font-text-lg-size"),F.literal("--font-heading-xs-size"),F.literal("--font-heading-sm-size"),F.literal("--font-heading-md-size"),F.literal("--font-heading-lg-size"),F.literal("--font-heading-xl-size"),F.literal("--font-heading-2xl-size"),F.literal("--font-heading-3xl-size"),F.literal("--font-text-xs-line-height"),F.literal("--font-text-sm-line-height"),F.literal("--font-text-md-line-height"),F.literal("--font-text-lg-line-height"),F.literal("--font-heading-xs-line-height"),F.literal("--font-heading-sm-line-height"),F.literal("--font-heading-md-line-height"),F.literal("--font-heading-lg-line-height"),F.literal("--font-heading-xl-line-height"),F.literal("--font-heading-2xl-line-height"),F.literal("--font-heading-3xl-line-height"),F.literal("--border-radius-xs"),F.literal("--border-radius-sm"),F.literal("--border-radius-md"),F.literal("--border-radius-lg"),F.literal("--border-radius-xl"),F.literal("--border-radius-full"),F.literal("--border-width-regular"),F.literal("--shadow-hairline"),F.literal("--shadow-sm"),F.literal("--shadow-md"),F.literal("--shadow-lg")]).describe("CSS variable keys available to MCP apps for theming."),OF=F.record(DF.describe(`Style variables for theming MCP apps.
Individual style keys are optional - hosts may provide any subset of these values.
Values are strings containing CSS values (colors, sizes, font stacks, etc.).
Note: This type uses \`Record<K, string | undefined>\` rather than \`Partial<Record<K, string>>\`
for compatibility with Zod schema generation. Both are functionally equivalent for validation.`),F.union([F.string(),F.undefined()]).describe(`Style variables for theming MCP apps.
Individual style keys are optional - hosts may provide any subset of these values.
Values are strings containing CSS values (colors, sizes, font stacks, etc.).
Note: This type uses \`Record<K, string | undefined>\` rather than \`Partial<Record<K, string>>\`
for compatibility with Zod schema generation. Both are functionally equivalent for validation.`)).describe(`Style variables for theming MCP apps.
Individual style keys are optional - hosts may provide any subset of these values.
Values are strings containing CSS values (colors, sizes, font stacks, etc.).
Note: This type uses \`Record<K, string | undefined>\` rather than \`Partial<Record<K, string>>\`
for compatibility with Zod schema generation. Both are functionally equivalent for validation.`),L=F.object({method:F.literal("ui/open-link"),params:F.object({url:F.string().describe("URL to open in the host's browser")})}),A=F.object({isError:F.boolean().optional().describe("True if the host failed to open the URL (e.g., due to security policy).")}).passthrough(),P=F.object({isError:F.boolean().optional().describe("True if the download failed (e.g., user cancelled or host denied).")}).passthrough(),I=F.object({isError:F.boolean().optional().describe("True if the host rejected or failed to deliver the message.")}).passthrough(),T=F.object({method:F.literal("ui/notifications/sandbox-proxy-ready"),params:F.object({})}),K=F.object({connectDomains:F.array(F.string()).optional().describe(`Origins for network requests (fetch/XHR/WebSocket).
- Maps to CSP \`connect-src\` directive
- Empty or omitted → no network connections (secure default)`),resourceDomains:F.array(F.string()).optional().describe("Origins for static resources (images, scripts, stylesheets, fonts, media).\n\n- Maps to CSP `img-src`, `script-src`, `style-src`, `font-src`, `media-src` directives\n- Wildcard subdomains supported: `https://*.example.com`\n- Empty or omitted → no network resources (secure default)"),frameDomains:F.array(F.string()).optional().describe("Origins for nested iframes.\n\n- Maps to CSP `frame-src` directive\n- Empty or omitted → no nested iframes allowed (`frame-src 'none'`)"),baseUriDomains:F.array(F.string()).optional().describe("Allowed base URIs for the document.\n\n- Maps to CSP `base-uri` directive\n- Empty or omitted → only same origin allowed (`base-uri 'self'`)")}),N=F.object({camera:F.object({}).optional().describe("Request camera access.\n\nMaps to Permission Policy `camera` feature."),microphone:F.object({}).optional().describe("Request microphone access.\n\nMaps to Permission Policy `microphone` feature."),geolocation:F.object({}).optional().describe("Request geolocation access.\n\nMaps to Permission Policy `geolocation` feature."),clipboardWrite:F.object({}).optional().describe("Request clipboard write access.\n\nMaps to Permission Policy `clipboard-write` feature.")}),w=F.object({method:F.literal("ui/notifications/size-changed"),params:F.object({width:F.number().optional().describe("New width in pixels."),height:F.number().optional().describe("New height in pixels.")})}),EF=F.object({method:F.literal("ui/notifications/tool-input"),params:F.object({arguments:F.record(F.string(),F.unknown().describe("Complete tool call arguments as key-value pairs.")).optional().describe("Complete tool call arguments as key-value pairs.")})}),HF=F.object({method:F.literal("ui/notifications/tool-input-partial"),params:F.object({arguments:F.record(F.string(),F.unknown().describe("Partial tool call arguments (incomplete, may change).")).optional().describe("Partial tool call arguments (incomplete, may change).")})}),VF=F.object({method:F.literal("ui/notifications/tool-cancelled"),params:F.object({reason:F.string().optional().describe('Optional reason for the cancellation (e.g., "user action", "timeout").')})}),h=F.object({fonts:F.string().optional()}),m=F.object({variables:OF.optional().describe("CSS variables for theming the app."),css:h.optional().describe("CSS blocks that apps can inject.")}),LF=F.object({method:F.literal("ui/resource-teardown"),params:F.object({})}),R=F.record(F.string(),F.unknown()),V=F.object({text:F.object({}).optional().describe("Host supports text content blocks."),image:F.object({}).optional().describe("Host supports image content blocks."),audio:F.object({}).optional().describe("Host supports audio content blocks."),resource:F.object({}).optional().describe("Host supports resource content blocks."),resourceLink:F.object({}).optional().describe("Host supports resource link content blocks."),structuredContent:F.object({}).optional().describe("Host supports structured content.")}),f=F.object({method:F.literal("ui/notifications/request-teardown"),params:F.object({}).optional()}),p=F.object({experimental:F.record(F.string(),F.record(F.string(),F.any()).describe("Experimental features keyed by identifier.")).optional().describe("Experimental features keyed by identifier."),openLinks:F.object({}).optional().describe("Host supports opening external URLs."),downloadFile:F.object({}).optional().describe("Host supports file downloads via ui/download-file."),serverTools:F.object({listChanged:F.boolean().optional().describe("Host supports tools/list_changed notifications.")}).optional().describe("Host can proxy tool calls to the MCP server."),serverResources:F.object({listChanged:F.boolean().optional().describe("Host supports resources/list_changed notifications.")}).optional().describe("Host can proxy resource reads to the MCP server."),logging:F.object({}).optional().describe("Host accepts log messages."),sandbox:F.object({permissions:N.optional().describe("Permissions granted by the host (camera, microphone, geolocation)."),csp:K.optional().describe("CSP domains approved by the host.")}).optional().describe("Sandbox configuration applied by the host."),updateModelContext:V.optional().describe("Host accepts context updates (ui/update-model-context) to be included in the model's context for future turns."),message:V.optional().describe("Host supports receiving content messages (ui/message) from the view."),sampling:F.object({tools:F.object({}).optional().describe("Host supports tool use via `tools` and `toolChoice` parameters.")}).optional().describe("Host supports LLM sampling (sampling/createMessage) from the view.\nMirrors the MCP `ClientCapabilities.sampling` shape so hosts can pass it through.")}),i=F.object({experimental:F.record(F.string(),F.record(F.string(),F.any()).describe("Experimental features keyed by identifier.")).optional().describe("Experimental features keyed by identifier."),tools:F.object({listChanged:F.boolean().optional().describe("App supports tools/list_changed notifications.")}).optional().describe("App exposes MCP-style tools that the host can call."),availableDisplayModes:F.array($).optional().describe("Display modes the app supports.")}),U=F.object({method:F.literal("ui/notifications/initialized"),params:F.object({}).optional()}),AF=F.object({csp:K.optional().describe("Content Security Policy configuration for UI resources."),permissions:N.optional().describe("Sandbox permissions requested by the UI resource."),domain:F.string().optional().describe(`Dedicated origin for view sandbox.
Useful when views need stable, dedicated origins for OAuth callbacks, CORS policies, or API key allowlists.
**Host-dependent:** The format and validation rules for this field are determined by each host. Servers MUST consult host-specific documentation for the expected domain format. Common patterns include:
- Hash-based subdomains (e.g., \`{hash}.claudemcpcontent.com\`)
- URL-derived subdomains (e.g., \`www-example-com.oaiusercontent.com\`)
If omitted, host uses default sandbox origin (typically per-conversation).`),prefersBorder:F.boolean().optional().describe(`Visual boundary preference - true if view prefers a visible border.
Boolean requesting whether a visible border and background is provided by the host. Specifying an explicit value for this is recommended because hosts' defaults may vary.
- \`true\`: request visible border + background
- \`false\`: request no visible border + background
- omitted: host decides border`)}),j=F.object({method:F.literal("ui/request-display-mode"),params:F.object({mode:$.describe("The display mode being requested.")})}),_=F.object({mode:$.describe("The display mode that was actually set. May differ from requested if not supported.")}).passthrough(),n=F.union([F.literal("model"),F.literal("app")]).describe("Tool visibility scope - who can access the tool."),PF=F.object({resourceUri:F.string().optional(),visibility:F.array(n).optional().describe(`Who can access this tool. Default: ["model", "app"]
- "model": Tool visible to and callable by the agent
- "app": Tool callable by the app from this server only`),csp:F.never().optional(),permissions:F.never().optional()}),vF=F.object({mimeTypes:F.array(F.string()).optional().describe('Array of supported MIME types for UI resources.\nMust include `"text/html;profile=mcp-app"` for MCP Apps support.')}),q=F.object({method:F.literal("ui/download-file"),params:F.object({contents:F.array(F.union([NF,_F])).describe("Resource contents to download — embedded (inline data) or linked (host fetches). Uses standard MCP resource types.")})}),y=F.object({method:F.literal("ui/message"),params:F.object({role:F.literal("user").describe('Message role, currently only "user" is supported.'),content:F.array(x).describe("Message content blocks (text, image, etc.).")})}),IF=F.object({method:F.literal("ui/notifications/sandbox-resource-ready"),params:F.object({html:F.string().describe("HTML content to load into the inner iframe."),sandbox:F.string().optional().describe("Optional override for the inner iframe's sandbox attribute."),csp:K.optional().describe("CSP configuration from resource metadata."),permissions:N.optional().describe("Sandbox permissions from resource metadata.")})}),TF=F.object({method:F.literal("ui/notifications/tool-result"),params:KF.describe("Standard MCP tool execution result.")}),C=F.object({toolInfo:F.object({id:jF.optional().describe("JSON-RPC id of the tools/call request."),tool:BF.describe("Tool definition including name, inputSchema, etc.")}).optional().describe("Metadata of the tool call that instantiated this App."),theme:d.optional().describe("Current color theme preference."),styles:m.optional().describe("Style configuration for theming the app."),displayMode:$.optional().describe("How the UI is currently displayed."),availableDisplayModes:F.array($).optional().describe("Display modes the host supports."),containerDimensions:F.union([F.object({height:F.number().describe("Fixed container height in pixels.")}),F.object({maxHeight:F.union([F.number(),F.undefined()]).optional().describe("Maximum container height in pixels.")})]).and(F.union([F.object({width:F.number().describe("Fixed container width in pixels.")}),F.object({maxWidth:F.union([F.number(),F.undefined()]).optional().describe("Maximum container width in pixels.")})])).optional().describe(`Container dimensions. Represents the dimensions of the iframe or other
container holding the app. Specify either width or maxWidth, and either height or maxHeight.`),locale:F.string().optional().describe("User's language and region preference in BCP 47 format."),timeZone:F.string().optional().describe("User's timezone in IANA format."),userAgent:F.string().optional().describe("Host application identifier."),platform:F.union([F.literal("web"),F.literal("desktop"),F.literal("mobile")]).optional().describe("Platform type for responsive design decisions."),deviceCapabilities:F.object({touch:F.boolean().optional().describe("Whether the device supports touch input."),hover:F.boolean().optional().describe("Whether the device supports hover interactions.")}).optional().describe("Device input capabilities."),safeAreaInsets:F.object({top:F.number().describe("Top safe area inset in pixels."),right:F.number().describe("Right safe area inset in pixels."),bottom:F.number().describe("Bottom safe area inset in pixels."),left:F.number().describe("Left safe area inset in pixels.")}).optional().describe("Mobile safe area boundaries in pixels.")}).passthrough(),wF=F.object({method:F.literal("ui/notifications/host-context-changed"),params:C.describe("Partial context update containing only changed fields.")}),M=F.object({method:F.literal("ui/update-model-context"),params:F.object({content:F.array(x).optional().describe("Context content blocks (text, image, etc.)."),structuredContent:F.record(F.string(),F.unknown().describe("Structured content for machine-readable context data.")).optional().describe("Structured content for machine-readable context data.")})}),S=F.object({method:F.literal("ui/initialize"),params:F.object({appInfo:v.describe("App identification (name and version)."),appCapabilities:i.describe("Features and capabilities this app provides."),protocolVersion:F.string().describe("Protocol version this app supports.")})}),g=F.object({protocolVersion:F.string().describe('Negotiated protocol version string (e.g., "2025-11-21").'),hostInfo:v.describe("Host application identification and version."),hostCapabilities:p.describe("Features and capabilities provided by the host."),hostContext:C.describe("Rich context about the host environment.")}).passthrough();var u="ui/resourceUri",RF="text/html;profile=mcp-app";import{JSONRPCMessageSchema as fF}from"@modelcontextprotocol/core";class c{eventTarget;eventSource;messageListener;constructor(G=window.parent,Q){this.eventTarget=G;this.eventSource=Q;this.messageListener=(W)=>{if(Q&&W.source!==this.eventSource){console.debug("Ignoring message from unknown source",W);return}let X=fF.safeParse(W.data);if(X.success)console.debug("Parsed message",X.data),this.onmessage?.(X.data);else if(W.data?.jsonrpc!=="2.0")console.debug("Ignoring non-JSON-RPC message",X.error.message,W);else console.error("Failed to parse message",X.error.message,W),this.onerror?.(Error("Invalid JSON-RPC message received: "+X.error.message))}}async start(){window.addEventListener("message",this.messageListener)}async send(G,Q){if(G.method!==H)console.debug("Sending message",G);this.eventTarget.postMessage(G,"*")}async close(){window.removeEventListener("message",this.messageListener),this.onclose?.()}onclose;onerror;onmessage;sessionId;setProtocolVersion}function AG(G){let W=G._meta?.ui?.resourceUri;if(W===void 0)W=G._meta?.[u];if(typeof W==="string"&&W.startsWith("ui://"))return W;else if(W!==void 0)throw Error(`Invalid UI resource URI: ${JSON.stringify(W)}`);return}function PG(G){let W=G._meta?.ui?.visibility;if(!W)return!1;if(W.length===1&&W[0]==="model")return!0;return!1}function IG(G){let W=G._meta?.ui?.visibility;if(!W)return!1;if(W.length===1&&W[0]==="app")return!0;return!1}function TG(G){if(!G)return"";let Q=[];if(G.camera)Q.push("camera");if(G.microphone)Q.push("microphone");if(G.geolocation)Q.push("geolocation");if(G.clipboardWrite)Q.push("clipboard-write");return Q.join("; ")}var CF=[J];class MF extends UF{_client;_hostInfo;_hostCapabilities;_appCapabilities;_hostContext={};_appInfo;_initializedReceived=!1;_registeredEvents=new Set;_events=new D;_methods=new O;setRequestHandler=(...G)=>{let[Q,...W]=E("request",G)??G;this._methods.claim(Q,"setRequestHandler"),super.setRequestHandler.call(this,Q,...W)};setNotificationHandler=(...G)=>{let[Q,...W]=E("notification",G)??G;this._methods.claim(Q,"setNotificationHandler"),super.setNotificationHandler.call(this,Q,...W)};removeRequestHandler=(G)=>{this._methods.release(G),super.removeRequestHandler(G)};removeNotificationHandler=(G)=>{this._methods.release(G),super.removeNotificationHandler(G)};replaceRequestHandler=(G,...Q)=>{this._methods.replace(G),super.setRequestHandler.call(this,G,...Q)};_wrapHandler(G,Q){let W=super._wrapHandler(G,Q);if(G==="ui/initialize"||G==="ping")return W;return async(X,Y)=>{if(!this._initializedReceived)console.warn(`[ext-apps] AppBridge received '${G}' before ui/notifications/initialized. The View is calling host methods before completing the handshake; it should await app.connect() first.`);return W(X,Y)}}eventSchemas={sizechange:w,sandboxready:T,initialized:U,requestteardown:f,loggingmessage:yF};setEventHandler(G,Q){this._ensureEventSlot(G),this._events.setHandler(G,Q)}getEventHandler(G){return this._events.getHandler(G)}addEventListener(G,Q){this._ensureEventSlot(G),this._events.addEventListener(G,Q)}removeEventListener(G,Q){this._events.removeEventListener(G,Q)}_ensureEventSlot(G){if(this._registeredEvents.has(G))return;let Q=this.eventSchemas[G];if(!Q)throw Error(`Unknown event: ${String(G)}`);let W=(X)=>{if(G==="initialized")this._initializedReceived=!0;this._events.dispatch(G,X)};if(G==="loggingmessage")this.setNotificationHandler("notifications/message",(X)=>{W(X.params)});else this.setNotificationHandler(Q.shape.method.value,{params:Q.shape.params},(X)=>W(X));this._registeredEvents.add(G)}warnIfRequestHandlerReplaced(G,Q,W){if(Q&&W)console.warn(`[MCP Apps] ${G} handler replaced. Previous handler will no longer be called.`)}constructor(G,Q,W,X){super(X);this._client=G;this._hostInfo=Q;this._hostCapabilities=W;this._methods.replace("notifications/cancelled"),this._methods.replace("notifications/progress"),this._ensureEventSlot("initialized"),this._hostContext=X?.hostContext||{},this.replaceRequestHandler("ui/initialize",{params:S.shape.params,result:g},(Y)=>this._onAppsInitialize(Y)),this.replaceRequestHandler("ping",(Y,Z)=>{return this.onping?.(Y.params,Z),{}}),this.replaceRequestHandler("ui/request-display-mode",{params:j.shape.params,result:_},()=>{return{mode:this._hostContext.displayMode??"inline"}})}buildContext(G){return G}assertCapabilityForMethod(G){}assertRequestHandlerCapability(G){}assertNotificationCapability(G){}getAppCapabilities(){return this._appCapabilities}getAppVersion(){return this._appInfo}onping;get onsizechange(){return this.getEventHandler("sizechange")}set onsizechange(G){this.setEventHandler("sizechange",G)}get onsandboxready(){return this.getEventHandler("sandboxready")}set onsandboxready(G){this.setEventHandler("sandboxready",G)}get oninitialized(){return this.getEventHandler("initialized")}set oninitialized(G){this.setEventHandler("initialized",G)}_onmessage;get onmessage(){return this._onmessage}set onmessage(G){this.warnIfRequestHandlerReplaced("onmessage",this._onmessage,G),this._onmessage=G,this.replaceRequestHandler("ui/message",{params:y.shape.params,result:I},async(Q,W)=>{if(!this._onmessage)throw Error("No onmessage handler set");return this._onmessage(Q,W)})}_onopenlink;get onopenlink(){return this._onopenlink}set onopenlink(G){this.warnIfRequestHandlerReplaced("onopenlink",this._onopenlink,G),this._onopenlink=G,this.replaceRequestHandler("ui/open-link",{params:L.shape.params,result:A},async(Q,W)=>{if(!this._onopenlink)throw Error("No onopenlink handler set");return this._onopenlink(Q,W)})}_ondownloadfile;get ondownloadfile(){return this._ondownloadfile}set ondownloadfile(G){this.warnIfRequestHandlerReplaced("ondownloadfile",this._ondownloadfile,G),this._ondownloadfile=G,this.replaceRequestHandler("ui/download-file",{params:q.shape.params,result:P},async(Q,W)=>{if(!this._ondownloadfile)throw Error("No ondownloadfile handler set");return this._ondownloadfile(Q,W)})}get onrequestteardown(){return this.getEventHandler("requestteardown")}set onrequestteardown(G){this.setEventHandler("requestteardown",G)}_onrequestdisplaymode;get onrequestdisplaymode(){return this._onrequestdisplaymode}set onrequestdisplaymode(G){this.warnIfRequestHandlerReplaced("onrequestdisplaymode",this._onrequestdisplaymode,G),this._onrequestdisplaymode=G,this.replaceRequestHandler("ui/request-display-mode",{params:j.shape.params,result:_},async(Q,W)=>{if(!this._onrequestdisplaymode)throw Error("No onrequestdisplaymode handler set");return this._onrequestdisplaymode(Q,W)})}get onloggingmessage(){return this.getEventHandler("loggingmessage")}set onloggingmessage(G){this.setEventHandler("loggingmessage",G)}_onupdatemodelcontext;get onupdatemodelcontext(){return this._onupdatemodelcontext}set onupdatemodelcontext(G){this.warnIfRequestHandlerReplaced("onupdatemodelcontext",this._onupdatemodelcontext,G),this._onupdatemodelcontext=G,this.replaceRequestHandler("ui/update-model-context",{params:M.shape.params,result:qF},async(Q,W)=>{if(!this._onupdatemodelcontext)throw Error("No onupdatemodelcontext handler set");return this._onupdatemodelcontext(Q,W)})}_oncalltool;get oncalltool(){return this._oncalltool}set oncalltool(G){this.warnIfRequestHandlerReplaced("oncalltool",this._oncalltool,G),this._oncalltool=G,this.replaceRequestHandler("tools/call",async(Q,W)=>{if(!this._oncalltool)throw Error("No oncalltool handler set");return this._oncalltool(Q.params,W)})}_oncreatesamplingmessage;get oncreatesamplingmessage(){return this._oncreatesamplingmessage}set oncreatesamplingmessage(G){this.warnIfRequestHandlerReplaced("oncreatesamplingmessage",this._oncreatesamplingmessage,G),this._oncreatesamplingmessage=G,this.replaceRequestHandler("sampling/createMessage",async(Q,W)=>{if(!this._oncreatesamplingmessage)throw Error("No oncreatesamplingmessage handler set");return this._oncreatesamplingmessage(Q.params,W)})}sendToolListChanged(G={}){return this.notification({method:"notifications/tools/list_changed",params:G})}_onlistresources;get onlistresources(){return this._onlistresources}set onlistresources(G){this.warnIfRequestHandlerReplaced("onlistresources",this._onlistresources,G),this._onlistresources=G,this.replaceRequestHandler("resources/list",async(Q,W)=>{if(!this._onlistresources)throw Error("No onlistresources handler set");return this._onlistresources(Q.params,W)})}_onlistresourcetemplates;get onlistresourcetemplates(){return this._onlistresourcetemplates}set onlistresourcetemplates(G){this.warnIfRequestHandlerReplaced("onlistresourcetemplates",this._onlistresourcetemplates,G),this._onlistresourcetemplates=G,this.replaceRequestHandler("resources/templates/list",async(Q,W)=>{if(!this._onlistresourcetemplates)throw Error("No onlistresourcetemplates handler set");return this._onlistresourcetemplates(Q.params,W)})}_onreadresource;get onreadresource(){return this._onreadresource}set onreadresource(G){this.warnIfRequestHandlerReplaced("onreadresource",this._onreadresource,G),this._onreadresource=G,this.replaceRequestHandler("resources/read",async(Q,W)=>{if(!this._onreadresource)throw Error("No onreadresource handler set");return this._onreadresource(Q.params,W)})}sendResourceListChanged(G={}){return this.notification({method:"notifications/resources/list_changed",params:G})}_onlistprompts;get onlistprompts(){return this._onlistprompts}set onlistprompts(G){this.warnIfRequestHandlerReplaced("onlistprompts",this._onlistprompts,G),this._onlistprompts=G,this.replaceRequestHandler("prompts/list",async(Q,W)=>{if(!this._onlistprompts)throw Error("No onlistprompts handler set");return this._onlistprompts(Q.params,W)})}sendPromptListChanged(G={}){return this.notification({method:"notifications/prompts/list_changed",params:G})}getCapabilities(){return this._hostCapabilities}async _onAppsInitialize(G){let Q=G.protocolVersion;if(this._appInfo!==void 0)console.warn("[ext-apps] AppBridge received a second ui/initialize. The View may be double-mounting (e.g. React StrictMode in dev) without closing the previous App instance. Responding normally; the latest appInfo/appCapabilities replace the previous values.");return this._appCapabilities=G.appCapabilities,this._appInfo=G.appInfo,{protocolVersion:CF.includes(Q)?Q:J,hostCapabilities:this.getCapabilities(),hostInfo:this._hostInfo,hostContext:this._hostContext}}setHostContext(G){let Q={},W=!1;for(let X of Object.keys(G)){let Y=this._hostContext[X],Z=G[X];if(SF(Y,Z))continue;Q[X]=Z,W=!0}if(W)this._hostContext=G,this.sendHostContextChange(Q)}sendHostContextChange(G){return this.notification({method:"ui/notifications/host-context-changed",params:G})}sendToolInput(G){return this.notification({method:"ui/notifications/tool-input",params:G})}sendToolInputPartial(G){return this.notification({method:"ui/notifications/tool-input-partial",params:G})}sendToolResult(G){return this.notification({method:"ui/notifications/tool-result",params:G})}sendToolCancelled(G){return this.notification({method:"ui/notifications/tool-cancelled",params:G})}sendSandboxResourceReady(G){return this.notification({method:"ui/notifications/sandbox-resource-ready",params:G})}teardownResource(G,Q){return this.request({method:"ui/resource-teardown",params:G},R,Q)}sendResourceTeardown=this.teardownResource;callTool(G,Q){return this.request({method:"tools/call",params:G},Q)}listTools(G,Q){return this.request({method:"tools/list",params:G},Q)}async connect(G){if(this.transport)throw Error("AppBridge is already connected. Call close() before connecting again.");if(this._initializedReceived=!1,this._client){let Q=this._client.getServerCapabilities();if(!Q)throw Error("Client server capabilities not available");if(Q.tools){if(this.oncalltool=async(W,X)=>{return this._client.request({method:"tools/call",params:W},{signal:X.mcpReq.signal})},Q.tools.listChanged)this._client.setNotificationHandler("notifications/tools/list_changed",(W)=>this.sendToolListChanged(W.params))}if(Q.resources){if(this.onlistresources=async(W,X)=>{return this._client.request({method:"resources/list",params:W},{signal:X.mcpReq.signal})},this.onlistresourcetemplates=async(W,X)=>{return this._client.request({method:"resources/templates/list",params:W},{signal:X.mcpReq.signal})},this.onreadresource=async(W,X)=>{return this._client.request({method:"resources/read",params:W},{signal:X.mcpReq.signal})},Q.resources.listChanged)this._client.setNotificationHandler("notifications/resources/list_changed",(W)=>this.sendResourceListChanged(W.params))}if(Q.prompts){if(this.onlistprompts=async(W,X)=>{return this._client.request({method:"prompts/list",params:W},{signal:X.mcpReq.signal})},Q.prompts.listChanged)this._client.setNotificationHandler("notifications/prompts/list_changed",(W)=>this.sendPromptListChanged(W.params))}}return super.connect(G)}}function SF(G,Q){return JSON.stringify(G)===JSON.stringify(Q)}export{PG as isToolVisibilityModelOnly,IG as isToolVisibilityAppOnly,AG as getToolUiResourceUri,TG as buildAllowAttribute,QF as TOOL_RESULT_METHOD,H as TOOL_INPUT_PARTIAL_METHOD,GF as TOOL_INPUT_METHOD,WF as TOOL_CANCELLED_METHOD,CF as SUPPORTED_PROTOCOL_VERSIONS,FF as SIZE_CHANGED_METHOD,e as SANDBOX_RESOURCE_READY_METHOD,a as SANDBOX_PROXY_READY_METHOD,u as RESOURCE_URI_META_KEY,ZF as RESOURCE_TEARDOWN_METHOD,RF as RESOURCE_MIME_TYPE,YF as REQUEST_TEARDOWN_METHOD,JF as REQUEST_DISPLAY_MODE_METHOD,c as PostMessageTransport,r as OPEN_LINK_METHOD,M as McpUiUpdateModelContextRequestSchema,n as McpUiToolVisibilitySchema,TF as McpUiToolResultNotificationSchema,PF as McpUiToolMetaSchema,HF as McpUiToolInputPartialNotificationSchema,EF as McpUiToolInputNotificationSchema,VF as McpUiToolCancelledNotificationSchema,d as McpUiThemeSchema,V as McpUiSupportedContentBlockModalitiesSchema,w as McpUiSizeChangedNotificationSchema,IF as McpUiSandboxResourceReadyNotificationSchema,T as McpUiSandboxProxyReadyNotificationSchema,R as McpUiResourceTeardownResultSchema,LF as McpUiResourceTeardownRequestSchema,N as McpUiResourcePermissionsSchema,AF as McpUiResourceMetaSchema,K as McpUiResourceCspSchema,f as McpUiRequestTeardownNotificationSchema,_ as McpUiRequestDisplayModeResultSchema,j as McpUiRequestDisplayModeRequestSchema,A as McpUiOpenLinkResultSchema,L as McpUiOpenLinkRequestSchema,I as McpUiMessageResultSchema,y as McpUiMessageRequestSchema,U as McpUiInitializedNotificationSchema,g as McpUiInitializeResultSchema,S as McpUiInitializeRequestSchema,m as McpUiHostStylesSchema,h as McpUiHostCssSchema,C as McpUiHostContextSchema,wF as McpUiHostContextChangedNotificationSchema,p as McpUiHostCapabilitiesSchema,P as McpUiDownloadFileResultSchema,q as McpUiDownloadFileRequestSchema,$ as McpUiDisplayModeSchema,i as McpUiAppCapabilitiesSchema,t as MESSAGE_METHOD,J as LATEST_PROTOCOL_VERSION,$F as INITIALIZE_METHOD,zF as INITIALIZED_METHOD,XF as HOST_CONTEXT_CHANGED_METHOD,s as DOWNLOAD_FILE_METHOD,MF as AppBridge};