@womp/mcp-ui 0.1.0 → 0.1.2
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 +91 -18
- package/dist/image/index.html +15 -27
- package/dist/index.js +4 -4
- package/dist/mesh/index.html +15 -27
- package/package.json +2 -1
- package/src/image/index.html +14 -26
- package/src/image/main.ts +7 -7
- package/src/mesh/index.html +14 -26
- package/src/mesh/main.ts +36 -12
- package/src/shared/bridge.ts +25 -0
package/README.md
CHANGED
|
@@ -57,9 +57,11 @@ _meta: { ui: { resourceUri: IMAGE_APP_URI }, "ui/resourceUri": IMAGE_APP_URI },
|
|
|
57
57
|
|
|
58
58
|
`get_generation` additionally needs `visibility: ["model", "app"]` — see below.
|
|
59
59
|
|
|
60
|
-
The cards
|
|
61
|
-
|
|
62
|
-
`
|
|
60
|
+
The cards read swan-backend's `GENERATION_OUTPUT_SCHEMA`: `status` /
|
|
61
|
+
`generationId` / `operationId` / `imageUrl` / `glbUrl` / `previewUrl`, plus
|
|
62
|
+
`model` and `durationSeconds` for the meta line described below. Every field is
|
|
63
|
+
optional except `status`, so a card is safe against a backend that predates any
|
|
64
|
+
of them — it just renders less.
|
|
63
65
|
|
|
64
66
|
## Things that will waste your day if you don't know them
|
|
65
67
|
|
|
@@ -143,6 +145,25 @@ replaced a day of MCP Tasks work with a polling loop.
|
|
|
143
145
|
**`get_generation` must declare `visibility: ["model", "app"]`.** Without
|
|
144
146
|
`"app"` the host refuses the call and the running state never resolves.
|
|
145
147
|
|
|
148
|
+
### What the card shows about a result
|
|
149
|
+
|
|
150
|
+
The line under the image is `8.77s · Nano Banana 2` — `durationSeconds` and
|
|
151
|
+
`model`, formatted the way swan-frontend's generation tile does
|
|
152
|
+
(`OperationModelTags.tsx`), two decimals included.
|
|
153
|
+
|
|
154
|
+
- **`durationSeconds` is the provider's own `stats.generation_time`**, not
|
|
155
|
+
wall-clock from the tool call. Queue wait is excluded, which is what makes it
|
|
156
|
+
the same number the Womp app shows for the same generation. Backend note: for
|
|
157
|
+
`generate_image` it comes off the result in hand rather than the DB row, since
|
|
158
|
+
`Operation.ext.stats` is written *after* the history resolves.
|
|
159
|
+
- **It is one of two lines, not one.** `#meta` is what produced the result;
|
|
160
|
+
`#status` is when something went wrong. They shared an element once and a
|
|
161
|
+
preview error erased the model name, or the reverse, depending on which
|
|
162
|
+
landed last. Both collapse when empty.
|
|
163
|
+
- **There is no generationId chip.** It was the first thing on the card and it
|
|
164
|
+
is an internal id: it means nothing to the reader, and the model gets it from
|
|
165
|
+
the tool's text response. Removed in 0.2.0.
|
|
166
|
+
|
|
146
167
|
### Display modes
|
|
147
168
|
|
|
148
169
|
`ctx.displayMode` is `inline` | `fullscreen` | `pip`. Cards are capped narrow
|
|
@@ -152,23 +173,51 @@ useless until CSS started keying off `:root[data-display-mode="fullscreen"]`.
|
|
|
152
173
|
|
|
153
174
|
## Development
|
|
154
175
|
|
|
155
|
-
|
|
176
|
+
**Do not iterate through Claude.** A card change reaches a connector only after
|
|
177
|
+
an npm publish, a swan-backend bump, a deploy, and a remove-and-re-add of the
|
|
178
|
+
connector. The repo ships its own host so that loop is only needed to confirm
|
|
179
|
+
the finished thing.
|
|
156
180
|
|
|
157
181
|
```bash
|
|
158
182
|
yarn install
|
|
159
|
-
yarn build # build:ui (two vite passes) + build:bake
|
|
160
183
|
yarn dev:mcp # stub MCP server on :3001 with fake slow generations
|
|
184
|
+
yarn dev # vite; opens the harness at /dev/host/index.html
|
|
161
185
|
```
|
|
162
186
|
|
|
163
|
-
|
|
164
|
-
|
|
187
|
+
Two terminals, then edit `src/` and watch the card hot-reload.
|
|
188
|
+
|
|
189
|
+
### The harness (`dev/host/`)
|
|
190
|
+
|
|
191
|
+
A real MCP Apps host: `AppBridge` from `@modelcontextprotocol/ext-apps`, driving
|
|
192
|
+
the card in an iframe and proxying its tool calls to the stub. Buttons for
|
|
193
|
+
card (image/mesh), tool call, theme, and display mode; a log of every message
|
|
194
|
+
that crosses the bridge.
|
|
195
|
+
|
|
196
|
+
It is deliberately faithful where being unfaithful would hide a bug:
|
|
197
|
+
|
|
198
|
+
| It reproduces | So you catch |
|
|
199
|
+
|---|---|
|
|
200
|
+
| iframe mounted hidden until `initialized` + a size report | a card that never calls `app.connect()` and is invisible in Claude |
|
|
201
|
+
| host style variables sent **only** over the bridge (and a toggle to withhold them) | a `var()` shipped without a fallback |
|
|
202
|
+
| the card's own `get_generation` polling, proxied to a real MCP server | a running state that never resolves |
|
|
203
|
+
| **"built resource" mode** — the exact HTML `resources/read` returns, in a sandboxed opaque-origin iframe | an asset `vite-plugin-singlefile` failed to inline (blank card) |
|
|
165
204
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
Claude renders it.
|
|
205
|
+
`FAKE_DURATION_MS=8000 yarn dev:mcp` lengthens a fake generation, so the
|
|
206
|
+
running → polling → complete transition is worth watching.
|
|
169
207
|
|
|
170
|
-
**
|
|
171
|
-
|
|
208
|
+
**Keep the tab visible.** A backgrounded tab does not run
|
|
209
|
+
`requestAnimationFrame` and clamps `setTimeout`, so auto-resize stops reporting
|
|
210
|
+
and the card's polling crawls — both look like card bugs and are not.
|
|
211
|
+
Headless/software-rendered browsers may also fail to create a WebGL context, in
|
|
212
|
+
which case the mesh card correctly falls back to the still image.
|
|
213
|
+
|
|
214
|
+
**The sandbox CSP is Claude's own** and cannot be reproduced here: a blocked
|
|
215
|
+
`media.womp.com` image or GLB only shows up there. The declared CSP is printed
|
|
216
|
+
under the stage so it can at least be read against the URLs in play.
|
|
217
|
+
|
|
218
|
+
### Confirming it in Claude
|
|
219
|
+
|
|
220
|
+
Still needed before shipping a card, because only Claude proves Claude:
|
|
172
221
|
|
|
173
222
|
```bash
|
|
174
223
|
ngrok http 3001 --url https://<reserved>.ngrok-free.dev
|
|
@@ -193,12 +242,36 @@ multiple inputs — so the cards build in **two separate passes** driven by a
|
|
|
193
242
|
|
|
194
243
|
## Releasing
|
|
195
244
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
245
|
+
Publishing is automated: tag and push, and `.github/workflows/publish.yml`
|
|
246
|
+
does the rest via **npm trusted publishing (OIDC)** — there is no `NPM_TOKEN`
|
|
247
|
+
secret.
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
git tag v0.1.1 && git push origin v0.1.1
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
The workflow resolves the version from the tag, writes it into `package.json`
|
|
254
|
+
**before** building, typechecks, builds, verifies the baked `ui://` URIs match
|
|
255
|
+
the tag, and publishes. It is a no-op if that version already exists on npm, so
|
|
256
|
+
re-running is safe. There is also a `workflow_dispatch` entry point if you need
|
|
257
|
+
to publish without tagging.
|
|
258
|
+
|
|
259
|
+
Do not commit a bumped `version` — the tag is the source of truth, and the
|
|
260
|
+
workflow sets it.
|
|
261
|
+
|
|
262
|
+
Afterwards: bump the dependency in swan-backend and deploy, then **users must
|
|
263
|
+
reconnect their connector** to see the change (see the resource-cache note
|
|
264
|
+
above).
|
|
265
|
+
|
|
266
|
+
### npm setup, once
|
|
267
|
+
|
|
268
|
+
Trusted publishing is configured per package, so the package must exist first:
|
|
269
|
+
|
|
270
|
+
1. publish `0.1.0` manually once (`npm publish` from a clean clone)
|
|
271
|
+
2. on npmjs.com → the package → Settings → **Trusted Publisher** → GitHub
|
|
272
|
+
Actions, with organization `wompxyz`, repository `mcp-ui`, workflow
|
|
273
|
+
`publish.yml`, and no environment
|
|
274
|
+
3. from then on, tags publish by themselves
|
|
202
275
|
|
|
203
276
|
## Known gaps
|
|
204
277
|
|
package/dist/image/index.html
CHANGED
|
@@ -63,25 +63,6 @@
|
|
|
63
63
|
.skeleton.pulsing { animation: none; }
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
/* Overlays float above the image, mirroring swan-frontend's generation
|
|
67
|
-
tile rather than sitting in a bar beneath it. */
|
|
68
|
-
.chips {
|
|
69
|
-
position: absolute;
|
|
70
|
-
top: 10px;
|
|
71
|
-
left: 10px;
|
|
72
|
-
display: flex;
|
|
73
|
-
gap: 6px;
|
|
74
|
-
}
|
|
75
|
-
.chip {
|
|
76
|
-
font-size: var(--font-text-xs-size, 11px);
|
|
77
|
-
padding: 3px 8px;
|
|
78
|
-
border-radius: var(--border-radius-full, 999px);
|
|
79
|
-
background: rgba(0, 0, 0, 0.55);
|
|
80
|
-
color: #fff;
|
|
81
|
-
backdrop-filter: blur(6px);
|
|
82
|
-
white-space: nowrap;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
66
|
.actions {
|
|
86
67
|
position: absolute;
|
|
87
68
|
bottom: 10px;
|
|
@@ -147,12 +128,19 @@
|
|
|
147
128
|
/* Nothing to reveal on hover when the image fills the screen. */
|
|
148
129
|
:root[data-display-mode="fullscreen"] .actions { opacity: 1; }
|
|
149
130
|
|
|
150
|
-
.status:empty
|
|
151
|
-
.
|
|
131
|
+
.status:empty,
|
|
132
|
+
.meta:empty { display: none; }
|
|
133
|
+
.status,
|
|
134
|
+
.meta {
|
|
152
135
|
font-size: var(--font-text-xs-size, 11px);
|
|
153
136
|
color: var(--color-text-secondary, rgba(232, 232, 232, 0.6));
|
|
154
137
|
padding: 8px 12px;
|
|
155
138
|
}
|
|
139
|
+
/* When both are shown the pair reads as one block, so the meta line drops
|
|
140
|
+
its bottom padding rather than double-spacing them. */
|
|
141
|
+
.meta:has(+ .status:not(:empty)) {
|
|
142
|
+
padding-bottom: 0;
|
|
143
|
+
}
|
|
156
144
|
</style>
|
|
157
145
|
<script type="module" crossorigin>var e=Object.defineProperty,t=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(e){throw n=[e],e}},n=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),r=(t,n)=>{let r={};for(var i in t)e(r,i,{get:t[i],enumerable:!0});return n||e(r,Symbol.toStringTag,{value:`Module`}),r},i=(e=>typeof require<`u`?require:typeof Proxy<`u`?new Proxy(e,{get:(e,t)=>(typeof require<`u`?require:e)[t]}):e)(function(e){if(typeof require<`u`)return require.apply(this,arguments);throw Error('Calling `require` for "'+e+"\" in an environment that doesn't expose the `require` function. See https://rolldown.rs/in-depth/bundling-cjs#require-external-modules for more details.")});(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();function a(e,t,n){function r(n,r){var i;Object.defineProperty(n,"_zod",{value:n._zod??{},enumerable:!1}),(i=n._zod).traits??(i.traits=new Set),n._zod.traits.add(e),t(n,r);for(let e in o.prototype)e in n||Object.defineProperty(n,e,{value:o.prototype[e].bind(n)});n._zod.constr=o,n._zod.def=r}let i=n?.Parent??Object;class a extends i{}Object.defineProperty(a,"name",{value:e});function o(e){var t;let i=n?.Parent?new a:this;r(i,e),(t=i._zod).deferred??(t.deferred=[]);for(let e of i._zod.deferred)e();return i}return Object.defineProperty(o,"init",{value:r}),Object.defineProperty(o,Symbol.hasInstance,{value:t=>n?.Parent&&t instanceof n.Parent?!0:t?._zod?.traits?.has(e)}),Object.defineProperty(o,"name",{value:e}),o}function o(e){return e&&Object.assign(u,e),u}var s,c,l,u,d=t((()=>{s=Object.freeze({status:`aborted`}),c=Symbol(`zod_brand`),l=class extends Error{constructor(){super(`Encountered Promise during synchronous parse. Use .parseAsync() instead.`)}},u={}})),f=r({BIGINT_FORMAT_RANGES:()=>ze,Class:()=>Be,NUMBER_FORMAT_RANGES:()=>Re,aborted:()=>De,allowsEval:()=>Pe,assert:()=>re,assertEqual:()=>p,assertIs:()=>te,assertNever:()=>ne,assertNotEqual:()=>ee,assignProp:()=>ue,cached:()=>oe,captureStackTrace:()=>Ne,cleanEnum:()=>Me,cleanRegex:()=>ce,clone:()=>g,createTransparentProxy:()=>ye,defineLazy:()=>h,esc:()=>me,escapeRegex:()=>ve,extend:()=>Ce,finalizeIssue:()=>b,floatSafeRemainder:()=>le,getElementAtPath:()=>de,getEnumValues:()=>ie,getLengthableOrigin:()=>Ae,getParsedType:()=>Fe,getSizableOrigin:()=>ke,isObject:()=>he,isPlainObject:()=>ge,issue:()=>je,joinValues:()=>m,jsonStringifyReplacer:()=>ae,merge:()=>we,normalizeParams:()=>_,nullish:()=>se,numKeys:()=>_e,omit:()=>Se,optionalKeys:()=>be,partial:()=>Te,pick:()=>xe,prefixIssues:()=>y,primitiveTypes:()=>Le,promiseAllObject:()=>fe,propertyKeyTypes:()=>Ie,randomString:()=>pe,required:()=>Ee,stringifyPrimitive:()=>v,unwrapMessage:()=>Oe});function p(e){return e}function ee(e){return e}function te(e){}function ne(e){throw Error()}function re(e){}function ie(e){let t=Object.values(e).filter(e=>typeof e==`number`);return Object.entries(e).filter(([e,n])=>t.indexOf(+e)===-1).map(([e,t])=>t)}function m(e,t=`|`){return e.map(e=>v(e)).join(t)}function ae(e,t){return typeof t==`bigint`?t.toString():t}function oe(e){return{get value(){{let t=e();return Object.defineProperty(this,"value",{value:t}),t}}}}function se(e){return e==null}function ce(e){let t=+!!e.startsWith(`^`),n=e.endsWith(`$`)?e.length-1:e.length;return e.slice(t,n)}function le(e,t){let n=(e.toString().split(`.`)[1]||``).length,r=(t.toString().split(`.`)[1]||``).length,i=n>r?n:r;return Number.parseInt(e.toFixed(i).replace(`.`,``))%Number.parseInt(t.toFixed(i).replace(`.`,``))/10**i}function h(e,t,n){Object.defineProperty(e,t,{get(){{let r=n();return e[t]=r,r}},set(n){Object.defineProperty(e,t,{value:n})},configurable:!0})}function ue(e,t,n){Object.defineProperty(e,t,{value:n,writable:!0,enumerable:!0,configurable:!0})}function de(e,t){return t?t.reduce((e,t)=>e?.[t],e):e}function fe(e){let t=Object.keys(e),n=t.map(t=>e[t]);return Promise.all(n).then(e=>{let n={};for(let r=0;r<t.length;r++)n[t[r]]=e[r];return n})}function pe(e=10){let t=``;for(let n=0;n<e;n++)t+=`abcdefghijklmnopqrstuvwxyz`[Math.floor(Math.random()*26)];return t}function me(e){return JSON.stringify(e)}function he(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function ge(e){if(he(e)===!1)return!1;let t=e.constructor;if(t===void 0)return!0;let n=t.prototype;return he(n)!==!1&&Object.prototype.hasOwnProperty.call(n,`isPrototypeOf`)!==!1}function _e(e){let t=0;for(let n in e)Object.prototype.hasOwnProperty.call(e,n)&&t++;return t}function ve(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function g(e,t,n){let r=new e._zod.constr(t??e._zod.def);return(!t||n?.parent)&&(r._zod.parent=e),r}function _(e){let t=e;if(!t)return{};if(typeof t==`string`)return{error:()=>t};if(t?.message!==void 0){if(t?.error!==void 0)throw Error("Cannot specify both `message` and `error` params");t.error=t.message}return delete t.message,typeof t.error==`string`?{...t,error:()=>t.error}:t}function ye(e){let t;return new Proxy({},{get(n,r,i){return t??=e(),Reflect.get(t,r,i)},set(n,r,i,a){return t??=e(),Reflect.set(t,r,i,a)},has(n,r){return t??=e(),Reflect.has(t,r)},deleteProperty(n,r){return t??=e(),Reflect.deleteProperty(t,r)},ownKeys(n){return t??=e(),Reflect.ownKeys(t)},getOwnPropertyDescriptor(n,r){return t??=e(),Reflect.getOwnPropertyDescriptor(t,r)},defineProperty(n,r,i){return t??=e(),Reflect.defineProperty(t,r,i)}})}function v(e){return typeof e==`bigint`?e.toString()+`n`:typeof e==`string`?`"${e}"`:`${e}`}function be(e){return Object.keys(e).filter(t=>e[t]._zod.optin===`optional`&&e[t]._zod.optout===`optional`)}function xe(e,t){let n={},r=e._zod.def;for(let e in t){if(!(e in r.shape))throw Error(`Unrecognized key: "${e}"`);t[e]&&(n[e]=r.shape[e])}return g(e,{...e._zod.def,shape:n,checks:[]})}function Se(e,t){let n={...e._zod.def.shape},r=e._zod.def;for(let e in t){if(!(e in r.shape))throw Error(`Unrecognized key: "${e}"`);t[e]&&delete n[e]}return g(e,{...e._zod.def,shape:n,checks:[]})}function Ce(e,t){if(!ge(t))throw Error(`Invalid input to extend: expected a plain object`);return g(e,{...e._zod.def,get shape(){let n={...e._zod.def.shape,...t};return ue(this,`shape`,n),n},checks:[]})}function we(e,t){return g(e,{...e._zod.def,get shape(){let n={...e._zod.def.shape,...t._zod.def.shape};return ue(this,`shape`,n),n},catchall:t._zod.def.catchall,checks:[]})}function Te(e,t,n){let r=t._zod.def.shape,i={...r};if(n)for(let t in n){if(!(t in r))throw Error(`Unrecognized key: "${t}"`);n[t]&&(i[t]=e?new e({type:`optional`,innerType:r[t]}):r[t])}else for(let t in r)i[t]=e?new e({type:`optional`,innerType:r[t]}):r[t];return g(t,{...t._zod.def,shape:i,checks:[]})}function Ee(e,t,n){let r=t._zod.def.shape,i={...r};if(n)for(let t in n){if(!(t in i))throw Error(`Unrecognized key: "${t}"`);n[t]&&(i[t]=new e({type:`nonoptional`,innerType:r[t]}))}else for(let t in r)i[t]=new e({type:`nonoptional`,innerType:r[t]});return g(t,{...t._zod.def,shape:i,checks:[]})}function De(e,t=0){for(let n=t;n<e.issues.length;n++)if(e.issues[n]?.continue!==!0)return!0;return!1}function y(e,t){return t.map(t=>{var n;return(n=t).path??(n.path=[]),t.path.unshift(e),t})}function Oe(e){return typeof e==`string`?e:e?.message}function b(e,t,n){let r={...e,path:e.path??[]};return e.message||(r.message=Oe(e.inst?._zod.def?.error?.(e))??Oe(t?.error?.(e))??Oe(n.customError?.(e))??Oe(n.localeError?.(e))??`Invalid input`),delete r.inst,delete r.continue,t?.reportInput||delete r.input,r}function ke(e){return e instanceof Set?`set`:e instanceof Map?`map`:e instanceof File?`file`:`unknown`}function Ae(e){return Array.isArray(e)?`array`:typeof e==`string`?`string`:`unknown`}function je(...e){let[t,n,r]=e;return typeof t==`string`?{message:t,code:`custom`,input:n,inst:r}:{...t}}function Me(e){return Object.entries(e).filter(([e,t])=>Number.isNaN(Number.parseInt(e,10))).map(e=>e[1])}var Ne,Pe,Fe,Ie,Le,Re,ze,Be,x=t((()=>{Ne=Error.captureStackTrace?Error.captureStackTrace:(...e)=>{},Pe=oe(()=>{if(typeof navigator<`u`&&navigator?.userAgent?.includes(`Cloudflare`))return!1;try{return Function(``),!0}catch{return!1}}),Fe=e=>{let t=typeof e;switch(t){case`undefined`:return`undefined`;case`string`:return`string`;case`number`:return Number.isNaN(e)?`nan`:`number`;case`boolean`:return`boolean`;case`function`:return`function`;case`bigint`:return`bigint`;case`symbol`:return`symbol`;case`object`:return Array.isArray(e)?`array`:e===null?`null`:e.then&&typeof e.then==`function`&&e.catch&&typeof e.catch==`function`?`promise`:typeof Map<`u`&&e instanceof Map?`map`:typeof Set<`u`&&e instanceof Set?`set`:typeof Date<`u`&&e instanceof Date?`date`:typeof File<`u`&&e instanceof File?`file`:`object`;default:throw Error(`Unknown data type: ${t}`)}},Ie=new Set([`string`,`number`,`symbol`]),Le=new Set([`string`,`number`,`bigint`,`boolean`,`symbol`,`undefined`]),Re={safeint:[-(2**53-1),2**53-1],int32:[-2147483648,2147483647],uint32:[0,4294967295],float32:[-34028234663852886e22,34028234663852886e22],float64:[-Number.MAX_VALUE,Number.MAX_VALUE]},ze={int64:[BigInt(`-9223372036854775808`),BigInt(`9223372036854775807`)],uint64:[BigInt(0),BigInt(`18446744073709551615`)]},Be=class{constructor(...e){}}}));function Ve(e,t=e=>e.message){let n={},r=[];for(let i of e.issues)i.path.length>0?(n[i.path[0]]=n[i.path[0]]||[],n[i.path[0]].push(t(i))):r.push(t(i));return{formErrors:r,fieldErrors:n}}function He(e,t){let n=t||function(e){return e.message},r={_errors:[]},i=e=>{for(let t of e.issues)if(t.code===`invalid_union`&&t.errors.length)t.errors.map(e=>i({issues:e}));else if(t.code===`invalid_key`)i({issues:t.issues});else if(t.code===`invalid_element`)i({issues:t.issues});else if(t.path.length===0)r._errors.push(n(t));else{let e=r,i=0;for(;i<t.path.length;){let r=t.path[i];i===t.path.length-1?(e[r]=e[r]||{_errors:[]},e[r]._errors.push(n(t))):e[r]=e[r]||{_errors:[]},e=e[r],i++}}};return i(e),r}function Ue(e,t){let n=t||function(e){return e.message},r={errors:[]},i=(e,t=[])=>{var a,o;for(let s of e.issues)if(s.code===`invalid_union`&&s.errors.length)s.errors.map(e=>i({issues:e},s.path));else if(s.code===`invalid_key`)i({issues:s.issues},s.path);else if(s.code===`invalid_element`)i({issues:s.issues},s.path);else{let e=[...t,...s.path];if(e.length===0){r.errors.push(n(s));continue}let i=r,c=0;for(;c<e.length;){let t=e[c],r=c===e.length-1;typeof t==`string`?(i.properties??(i.properties={}),(a=i.properties)[t]??(a[t]={errors:[]}),i=i.properties[t]):(i.items??(i.items=[]),(o=i.items)[t]??(o[t]={errors:[]}),i=i.items[t]),r&&i.errors.push(n(s)),c++}}};return i(e),r}function We(e){let t=[];for(let n of e)typeof n==`number`?t.push(`[${n}]`):typeof n==`symbol`?t.push(`[${JSON.stringify(String(n))}]`):/[^\w$]/.test(n)?t.push(`[${JSON.stringify(n)}]`):(t.length&&t.push(`.`),t.push(n));return t.join(``)}function Ge(e){let t=[],n=[...e.issues].sort((e,t)=>e.path.length-t.path.length);for(let e of n)t.push(`✖ ${e.message}`),e.path?.length&&t.push(` → at ${We(e.path)}`);return t.join(`
|
|
158
146
|
`)}var Ke,qe,Je,Ye=t((()=>{d(),x(),Ke=(e,t)=>{e.name=`$ZodError`,Object.defineProperty(e,"_zod",{value:e._zod,enumerable:!1}),Object.defineProperty(e,"issues",{value:t,enumerable:!1}),Object.defineProperty(e,"message",{get(){return JSON.stringify(t,ae,2)},enumerable:!0}),Object.defineProperty(e,"toString",{value:()=>e.message,enumerable:!1})},qe=a(`$ZodError`,Ke),Je=a(`$ZodError`,Ke,{Parent:Error})})),Xe,Ze,Qe,$e,et,tt,nt,rt,it=t((()=>{d(),Ye(),x(),Xe=e=>(t,n,r,i)=>{let a=r?Object.assign(r,{async:!1}):{async:!1},s=t._zod.run({value:n,issues:[]},a);if(s instanceof Promise)throw new l;if(s.issues.length){let t=new((i?.Err)??e)(s.issues.map(e=>b(e,a,o())));throw Ne(t,i?.callee),t}return s.value},Ze=Xe(Je),Qe=e=>async(t,n,r,i)=>{let a=r?Object.assign(r,{async:!0}):{async:!0},s=t._zod.run({value:n,issues:[]},a);if(s instanceof Promise&&(s=await s),s.issues.length){let t=new((i?.Err)??e)(s.issues.map(e=>b(e,a,o())));throw Ne(t,i?.callee),t}return s.value},$e=Qe(Je),et=e=>(t,n,r)=>{let i=r?{...r,async:!1}:{async:!1},a=t._zod.run({value:n,issues:[]},i);if(a instanceof Promise)throw new l;return a.issues.length?{success:!1,error:new(e??qe)(a.issues.map(e=>b(e,i,o())))}:{success:!0,data:a.value}},tt=et(Je),nt=e=>async(t,n,r)=>{let i=r?Object.assign(r,{async:!0}):{async:!0},a=t._zod.run({value:n,issues:[]},i);return a instanceof Promise&&(a=await a),a.issues.length?{success:!1,error:new e(a.issues.map(e=>b(e,i,o())))}:{success:!0,data:a.value}},rt=nt(Je)})),at=r({_emoji:()=>Ot,base64:()=>Nt,base64url:()=>Pt,bigint:()=>Vt,boolean:()=>Wt,browserEmail:()=>Dt,cidrv4:()=>jt,cidrv6:()=>Mt,cuid:()=>ut,cuid2:()=>dt,date:()=>zt,datetime:()=>lt,domain:()=>It,duration:()=>gt,e164:()=>Lt,email:()=>Ct,emoji:()=>ot,extendedDuration:()=>_t,guid:()=>vt,hostname:()=>Ft,html5Email:()=>wt,integer:()=>Ht,ipv4:()=>kt,ipv6:()=>At,ksuid:()=>mt,lowercase:()=>qt,nanoid:()=>ht,null:()=>Gt,number:()=>Ut,rfc5322Email:()=>Tt,string:()=>Bt,time:()=>ct,ulid:()=>ft,undefined:()=>Kt,unicodeEmail:()=>Et,uppercase:()=>Jt,uuid:()=>yt,uuid4:()=>bt,uuid6:()=>xt,uuid7:()=>St,xid:()=>pt});function ot(){return new RegExp(Ot,`u`)}function st(e){let t=`(?:[01]\\d|2[0-3]):[0-5]\\d`;return typeof e.precision==`number`?e.precision===-1?`${t}`:e.precision===0?`${t}:[0-5]\\d`:`${t}:[0-5]\\d\\.\\d{${e.precision}}`:`${t}(?::[0-5]\\d(?:\\.\\d+)?)?`}function ct(e){return RegExp(`^${st(e)}$`)}function lt(e){let t=st({precision:e.precision}),n=[`Z`];e.local&&n.push(``),e.offset&&n.push(`([+-]\\d{2}:\\d{2})`);let r=`${t}(?:${n.join(`|`)})`;return RegExp(`^${Rt}T(?:${r})$`)}var ut,dt,ft,pt,mt,ht,gt,_t,vt,yt,bt,xt,St,Ct,wt,Tt,Et,Dt,Ot,kt,At,jt,Mt,Nt,Pt,Ft,It,Lt,Rt,zt,Bt,Vt,Ht,Ut,Wt,Gt,Kt,qt,Jt,Yt=t((()=>{ut=/^[cC][^\s-]{8,}$/,dt=/^[0-9a-z]+$/,ft=/^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/,pt=/^[0-9a-vA-V]{20}$/,mt=/^[A-Za-z0-9]{27}$/,ht=/^[a-zA-Z0-9_-]{21}$/,gt=/^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/,_t=/^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/,vt=/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/,yt=e=>e?RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${e}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`):/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$/,bt=yt(4),xt=yt(6),St=yt(7),Ct=/^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$/,wt=/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,Tt=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,Et=/^[^\s@"]{1,64}@[^\s@]{1,255}$/u,Dt=/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,Ot=`^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`,kt=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,At=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})$/,jt=/^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/,Mt=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,Nt=/^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/,Pt=/^[A-Za-z0-9_-]*$/,Ft=/^([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+$/,It=/^([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/,Lt=/^\+(?:[0-9]){6,14}[0-9]$/,Rt=`(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))`,zt=RegExp(`^${Rt}$`),Bt=e=>{let t=e?`[\\s\\S]{${e?.minimum??0},${e?.maximum??``}}`:`[\\s\\S]*`;return RegExp(`^${t}$`)},Vt=/^\d+n?$/,Ht=/^\d+$/,Ut=/^-?\d+(?:\.\d+)?/i,Wt=/true|false/i,Gt=/null/i,Kt=/undefined/i,qt=/^[^A-Z]*$/,Jt=/^[^a-z]*$/}));function Xt(e,t,n){e.issues.length&&t.issues.push(...y(n,e.issues))}var S,Zt,Qt,$t,en,tn,nn,rn,an,on,sn,cn,ln,un,dn,fn,pn,mn,hn,gn,_n,vn,yn,bn=t((()=>{d(),Yt(),x(),S=a(`$ZodCheck`,(e,t)=>{var n;e._zod??={},e._zod.def=t,(n=e._zod).onattach??(n.onattach=[])}),Zt={number:`number`,bigint:`bigint`,object:`date`},Qt=a(`$ZodCheckLessThan`,(e,t)=>{S.init(e,t);let n=Zt[typeof t.value];e._zod.onattach.push(e=>{let n=e._zod.bag,r=(t.inclusive?n.maximum:n.exclusiveMaximum)??1/0;t.value<r&&(t.inclusive?n.maximum=t.value:n.exclusiveMaximum=t.value)}),e._zod.check=r=>{(t.inclusive?r.value<=t.value:r.value<t.value)||r.issues.push({origin:n,code:`too_big`,maximum:t.value,input:r.value,inclusive:t.inclusive,inst:e,continue:!t.abort})}}),$t=a(`$ZodCheckGreaterThan`,(e,t)=>{S.init(e,t);let n=Zt[typeof t.value];e._zod.onattach.push(e=>{let n=e._zod.bag,r=(t.inclusive?n.minimum:n.exclusiveMinimum)??-1/0;t.value>r&&(t.inclusive?n.minimum=t.value:n.exclusiveMinimum=t.value)}),e._zod.check=r=>{(t.inclusive?r.value>=t.value:r.value>t.value)||r.issues.push({origin:n,code:`too_small`,minimum:t.value,input:r.value,inclusive:t.inclusive,inst:e,continue:!t.abort})}}),en=a(`$ZodCheckMultipleOf`,(e,t)=>{S.init(e,t),e._zod.onattach.push(e=>{var n;(n=e._zod.bag).multipleOf??(n.multipleOf=t.value)}),e._zod.check=n=>{if(typeof n.value!=typeof t.value)throw Error(`Cannot mix number and bigint in multiple_of check.`);(typeof n.value==`bigint`?n.value%t.value===BigInt(0):le(n.value,t.value)===0)||n.issues.push({origin:typeof n.value,code:`not_multiple_of`,divisor:t.value,input:n.value,inst:e,continue:!t.abort})}}),tn=a(`$ZodCheckNumberFormat`,(e,t)=>{S.init(e,t),t.format=t.format||`float64`;let n=t.format?.includes(`int`),r=n?`int`:`number`,[i,a]=Re[t.format];e._zod.onattach.push(e=>{let r=e._zod.bag;r.format=t.format,r.minimum=i,r.maximum=a,n&&(r.pattern=Ht)}),e._zod.check=o=>{let s=o.value;if(n){if(!Number.isInteger(s)){o.issues.push({expected:r,format:t.format,code:`invalid_type`,input:s,inst:e});return}if(!Number.isSafeInteger(s)){s>0?o.issues.push({input:s,code:`too_big`,maximum:2**53-1,note:`Integers must be within the safe integer range.`,inst:e,origin:r,continue:!t.abort}):o.issues.push({input:s,code:`too_small`,minimum:-(2**53-1),note:`Integers must be within the safe integer range.`,inst:e,origin:r,continue:!t.abort});return}}s<i&&o.issues.push({origin:`number`,input:s,code:`too_small`,minimum:i,inclusive:!0,inst:e,continue:!t.abort}),s>a&&o.issues.push({origin:`number`,input:s,code:`too_big`,maximum:a,inst:e})}}),nn=a(`$ZodCheckBigIntFormat`,(e,t)=>{S.init(e,t);let[n,r]=ze[t.format];e._zod.onattach.push(e=>{let i=e._zod.bag;i.format=t.format,i.minimum=n,i.maximum=r}),e._zod.check=i=>{let a=i.value;a<n&&i.issues.push({origin:`bigint`,input:a,code:`too_small`,minimum:n,inclusive:!0,inst:e,continue:!t.abort}),a>r&&i.issues.push({origin:`bigint`,input:a,code:`too_big`,maximum:r,inst:e})}}),rn=a(`$ZodCheckMaxSize`,(e,t)=>{var n;S.init(e,t),(n=e._zod.def).when??(n.when=e=>{let t=e.value;return!se(t)&&t.size!==void 0}),e._zod.onattach.push(e=>{let n=e._zod.bag.maximum??1/0;t.maximum<n&&(e._zod.bag.maximum=t.maximum)}),e._zod.check=n=>{let r=n.value;r.size<=t.maximum||n.issues.push({origin:ke(r),code:`too_big`,maximum:t.maximum,input:r,inst:e,continue:!t.abort})}}),an=a(`$ZodCheckMinSize`,(e,t)=>{var n;S.init(e,t),(n=e._zod.def).when??(n.when=e=>{let t=e.value;return!se(t)&&t.size!==void 0}),e._zod.onattach.push(e=>{let n=e._zod.bag.minimum??-1/0;t.minimum>n&&(e._zod.bag.minimum=t.minimum)}),e._zod.check=n=>{let r=n.value;r.size>=t.minimum||n.issues.push({origin:ke(r),code:`too_small`,minimum:t.minimum,input:r,inst:e,continue:!t.abort})}}),on=a(`$ZodCheckSizeEquals`,(e,t)=>{var n;S.init(e,t),(n=e._zod.def).when??(n.when=e=>{let t=e.value;return!se(t)&&t.size!==void 0}),e._zod.onattach.push(e=>{let n=e._zod.bag;n.minimum=t.size,n.maximum=t.size,n.size=t.size}),e._zod.check=n=>{let r=n.value,i=r.size;if(i===t.size)return;let a=i>t.size;n.issues.push({origin:ke(r),...a?{code:`too_big`,maximum:t.size}:{code:`too_small`,minimum:t.size},inclusive:!0,exact:!0,input:n.value,inst:e,continue:!t.abort})}}),sn=a(`$ZodCheckMaxLength`,(e,t)=>{var n;S.init(e,t),(n=e._zod.def).when??(n.when=e=>{let t=e.value;return!se(t)&&t.length!==void 0}),e._zod.onattach.push(e=>{let n=e._zod.bag.maximum??1/0;t.maximum<n&&(e._zod.bag.maximum=t.maximum)}),e._zod.check=n=>{let r=n.value;if(r.length<=t.maximum)return;let i=Ae(r);n.issues.push({origin:i,code:`too_big`,maximum:t.maximum,inclusive:!0,input:r,inst:e,continue:!t.abort})}}),cn=a(`$ZodCheckMinLength`,(e,t)=>{var n;S.init(e,t),(n=e._zod.def).when??(n.when=e=>{let t=e.value;return!se(t)&&t.length!==void 0}),e._zod.onattach.push(e=>{let n=e._zod.bag.minimum??-1/0;t.minimum>n&&(e._zod.bag.minimum=t.minimum)}),e._zod.check=n=>{let r=n.value;if(r.length>=t.minimum)return;let i=Ae(r);n.issues.push({origin:i,code:`too_small`,minimum:t.minimum,inclusive:!0,input:r,inst:e,continue:!t.abort})}}),ln=a(`$ZodCheckLengthEquals`,(e,t)=>{var n;S.init(e,t),(n=e._zod.def).when??(n.when=e=>{let t=e.value;return!se(t)&&t.length!==void 0}),e._zod.onattach.push(e=>{let n=e._zod.bag;n.minimum=t.length,n.maximum=t.length,n.length=t.length}),e._zod.check=n=>{let r=n.value,i=r.length;if(i===t.length)return;let a=Ae(r),o=i>t.length;n.issues.push({origin:a,...o?{code:`too_big`,maximum:t.length}:{code:`too_small`,minimum:t.length},inclusive:!0,exact:!0,input:n.value,inst:e,continue:!t.abort})}}),un=a(`$ZodCheckStringFormat`,(e,t)=>{var n,r;S.init(e,t),e._zod.onattach.push(e=>{let n=e._zod.bag;n.format=t.format,t.pattern&&(n.patterns??=new Set,n.patterns.add(t.pattern))}),t.pattern?(n=e._zod).check??(n.check=n=>{t.pattern.lastIndex=0,!t.pattern.test(n.value)&&n.issues.push({origin:`string`,code:`invalid_format`,format:t.format,input:n.value,...t.pattern?{pattern:t.pattern.toString()}:{},inst:e,continue:!t.abort})}):(r=e._zod).check??(r.check=()=>{})}),dn=a(`$ZodCheckRegex`,(e,t)=>{un.init(e,t),e._zod.check=n=>{t.pattern.lastIndex=0,!t.pattern.test(n.value)&&n.issues.push({origin:`string`,code:`invalid_format`,format:`regex`,input:n.value,pattern:t.pattern.toString(),inst:e,continue:!t.abort})}}),fn=a(`$ZodCheckLowerCase`,(e,t)=>{t.pattern??=qt,un.init(e,t)}),pn=a(`$ZodCheckUpperCase`,(e,t)=>{t.pattern??=Jt,un.init(e,t)}),mn=a(`$ZodCheckIncludes`,(e,t)=>{S.init(e,t);let n=ve(t.includes),r=new RegExp(typeof t.position==`number`?`^.{${t.position}}${n}`:n);t.pattern=r,e._zod.onattach.push(e=>{let t=e._zod.bag;t.patterns??=new Set,t.patterns.add(r)}),e._zod.check=n=>{n.value.includes(t.includes,t.position)||n.issues.push({origin:`string`,code:`invalid_format`,format:`includes`,includes:t.includes,input:n.value,inst:e,continue:!t.abort})}}),hn=a(`$ZodCheckStartsWith`,(e,t)=>{S.init(e,t);let n=RegExp(`^${ve(t.prefix)}.*`);t.pattern??=n,e._zod.onattach.push(e=>{let t=e._zod.bag;t.patterns??=new Set,t.patterns.add(n)}),e._zod.check=n=>{n.value.startsWith(t.prefix)||n.issues.push({origin:`string`,code:`invalid_format`,format:`starts_with`,prefix:t.prefix,input:n.value,inst:e,continue:!t.abort})}}),gn=a(`$ZodCheckEndsWith`,(e,t)=>{S.init(e,t);let n=RegExp(`.*${ve(t.suffix)}$`);t.pattern??=n,e._zod.onattach.push(e=>{let t=e._zod.bag;t.patterns??=new Set,t.patterns.add(n)}),e._zod.check=n=>{n.value.endsWith(t.suffix)||n.issues.push({origin:`string`,code:`invalid_format`,format:`ends_with`,suffix:t.suffix,input:n.value,inst:e,continue:!t.abort})}}),_n=a(`$ZodCheckProperty`,(e,t)=>{S.init(e,t),e._zod.check=e=>{let n=t.schema._zod.run({value:e.value[t.property],issues:[]},{});if(n instanceof Promise)return n.then(n=>Xt(n,e,t.property));Xt(n,e,t.property)}}),vn=a(`$ZodCheckMimeType`,(e,t)=>{S.init(e,t);let n=new Set(t.mime);e._zod.onattach.push(e=>{e._zod.bag.mime=t.mime}),e._zod.check=r=>{n.has(r.value.type)||r.issues.push({code:`invalid_value`,values:t.mime,input:r.value.type,inst:e})}}),yn=a(`$ZodCheckOverwrite`,(e,t)=>{S.init(e,t),e._zod.check=e=>{e.value=t.tx(e.value)}})})),xn,Sn=t((()=>{xn=class{constructor(e=[]){this.content=[],this.indent=0,this&&(this.args=e)}indented(e){this.indent+=1,e(this),--this.indent}write(e){if(typeof e==`function`){e(this,{execution:`sync`}),e(this,{execution:`async`});return}let t=e.split(`
|
|
@@ -228,18 +216,13 @@ Boolean requesting whether a visible border and background is provided by the ho
|
|
|
228
216
|
- omitted: host decides border`)}),F({method:B(`ui/request-display-mode`),params:F({mode:Uh.describe(`The display mode being requested.`)})}),og=F({mode:Uh.describe(`The display mode that was actually set. May differ from requested if not supported.`)}).passthrough(),sg=L([B(`model`),B(`app`)]).describe(`Tool visibility scope - who can access the tool.`),F({resourceUri:A().optional(),visibility:P(sg).optional().describe(`Who can access this tool. Default: ["model", "app"]
|
|
229
217
|
- "model": Tool visible to and callable by the agent
|
|
230
218
|
- "app": Tool callable by the app from this server only`),csp:Hl().optional(),permissions:Hl().optional()}),F({mimeTypes:P(A()).optional().describe('Array of supported MIME types for UI resources.\nMust include `"text/html;profile=mcp-app"` for MCP Apps support.')}),F({method:B(`ui/download-file`),params:F({contents:P(L([kp,Ap])).describe(`Resource contents to download — embedded (inline data) or linked (host fetches). Uses standard MCP resource types.`)})}),F({method:B(`ui/message`),params:F({role:B(`user`).describe(`Message role, currently only "user" is supported.`),content:P(jp).describe(`Message content blocks (text, image, etc.).`)})}),F({method:B(`ui/notifications/sandbox-resource-ready`),params:F({html:A().describe(`HTML content to load into the inner iframe.`),sandbox:A().optional().describe(`Optional override for the inner iframe's sandbox attribute.`),csp:Yh.optional().describe(`CSP configuration from resource metadata.`),permissions:Xh.optional().describe(`Sandbox permissions from resource metadata.`)})}),cg=F({method:B(`ui/notifications/tool-result`),params:Bp.describe(`Standard MCP tool execution result.`)}),lg=F({toolInfo:F({id:rf.optional().describe(`JSON-RPC id of the tools/call request.`),tool:Lp.describe(`Tool definition including name, inputSchema, etc.`)}).optional().describe(`Metadata of the tool call that instantiated this App.`),theme:Hh.optional().describe(`Current color theme preference.`),styles:tg.optional().describe(`Style configuration for theming the app.`),displayMode:Uh.optional().describe(`How the UI is currently displayed.`),availableDisplayModes:P(Uh).optional().describe(`Display modes the host supports.`),containerDimensions:L([F({height:j().describe(`Fixed container height in pixels.`)}),F({maxHeight:L([j(),zl()]).optional().describe(`Maximum container height in pixels.`)})]).and(L([F({width:j().describe(`Fixed container width in pixels.`)}),F({maxWidth:L([j(),zl()]).optional().describe(`Maximum container width in pixels.`)})])).optional().describe(`Container dimensions. Represents the dimensions of the iframe or other
|
|
231
|
-
container holding the app. Specify either width or maxWidth, and either height or maxHeight.`),locale:A().optional().describe(`User's language and region preference in BCP 47 format.`),timeZone:A().optional().describe(`User's timezone in IANA format.`),userAgent:A().optional().describe(`Host application identifier.`),platform:L([B(`web`),B(`desktop`),B(`mobile`)]).optional().describe(`Platform type for responsive design decisions.`),deviceCapabilities:F({touch:M().optional().describe(`Whether the device supports touch input.`),hover:M().optional().describe(`Whether the device supports hover interactions.`)}).optional().describe(`Device input capabilities.`),safeAreaInsets:F({top:j().describe(`Top safe area inset in pixels.`),right:j().describe(`Right safe area inset in pixels.`),bottom:j().describe(`Bottom safe area inset in pixels.`),left:j().describe(`Left safe area inset in pixels.`)}).optional().describe(`Mobile safe area boundaries in pixels.`)}).passthrough(),ug=F({method:B(`ui/notifications/host-context-changed`),params:lg.describe(`Partial context update containing only changed fields.`)}),F({method:B(`ui/update-model-context`),params:F({content:P(jp).optional().describe(`Context content blocks (text, image, etc.).`),structuredContent:R(A(),N().describe(`Structured content for machine-readable context data.`)).optional().describe(`Structured content for machine-readable context data.`)})}),F({method:B(`ui/initialize`),params:F({appInfo:bf.describe(`App identification (name and version).`),appCapabilities:ag.describe(`Features and capabilities this app provides.`),protocolVersion:A().describe(`Protocol version this app supports.`)})}),dg=F({protocolVersion:A().describe(`Negotiated protocol version string (e.g., "2025-11-21").`),hostInfo:bf.describe(`Host application identification and version.`),hostCapabilities:ig.describe(`Features and capabilities provided by the host.`),hostContext:lg.describe(`Rich context about the host environment.`)}).passthrough(),fg={target:`draft-2020-12`},pg=class e extends zh{_appInfo;_capabilities;options;_hostCapabilities;_hostInfo;_hostContext;_registeredTools={};_initializedSent=!1;_assertInitialized(e){if(this._initializedSent)return;let t=`[ext-apps] App.${e}() called before connect() completed the ui/initialize handshake. Await app.connect() before calling this method, or move data loading to an ontoolresult handler.`;if(this.options?.strict)throw Error(t);console.warn(`${t}. This will throw in a future release.`)}eventSchemas={toolinput:Zh,toolinputpartial:Qh,toolresult:cg,toolcancelled:$h,hostcontextchanged:ug};static ONE_SHOT_EVENTS=new Set([`toolinput`,`toolinputpartial`,`toolresult`,`toolcancelled`]);_everHadListener=new Set;_assertHandlerTiming(t){if(!e.ONE_SHOT_EVENTS.has(t)||this._everHadListener.has(t)||(this._everHadListener.add(t),!this._initializedSent))return;let n=`[ext-apps] "${String(t)}" handler registered after connect() completed the ui/initialize handshake. The host may have already sent this notification. Register handlers before calling app.connect().`;if(this.options?.strict)throw Error(n);console.warn(n)}setEventHandler(e,t){t&&this._assertHandlerTiming(e),super.setEventHandler(e,t)}addEventListener(e,t){this._assertHandlerTiming(e),super.addEventListener(e,t)}onEventDispatch(e,t){e===`hostcontextchanged`&&(this._hostContext={...this._hostContext,...t})}constructor(e,t={},n={autoResize:!0}){super(n),this._appInfo=e,this._capabilities=t,this.options=n,n.allowUnsafeEval||o({jitless:!0}),this.setRequestHandler(jf,e=>(console.log(`Received ping:`,e.params),{})),this.setEventHandler(`hostcontextchanged`,void 0)}registerCapabilities(e){if(this.transport)throw Error(`Cannot register capabilities after transport is established`);this._capabilities=Dh(this._capabilities,e)}registerTool(e,t,n){if(this._registeredTools[e])throw Error(`Tool ${e} is already registered`);let r=this,i=()=>{r._initializedSent&&r._capabilities.tools?.listChanged&&r.sendToolListChanged()},a=t.inputSchema!==void 0,o={title:t.title,description:t.description,inputSchema:t.inputSchema,outputSchema:t.outputSchema,annotations:t.annotations,_meta:t._meta,enabled:!0,enable(){this.enabled=!0,i()},disable(){this.enabled=!1,i()},update(e){Object.assign(this,e),i()},remove(){r._registeredTools[e]===o&&(delete r._registeredTools[e],i())},handler:async(t,r)=>{if(!o.enabled)throw Error(`Tool ${e} is disabled`);let i;if(a){let a=o.inputSchema;i=await n(a?await Ih(a,t??{},`Invalid input for tool ${e}: `):t??{},r)}else i=await n(r);return o.outputSchema&&!i.isError&&(i.structuredContent=await Ih(o.outputSchema,i.structuredContent,`Invalid output for tool ${e}: `)),i}};return this._registeredTools[e]=o,!this._capabilities.tools&&!this.transport&&this.registerCapabilities({tools:{listChanged:!0}}),this.ensureToolHandlersInitialized(),i(),o}_toolHandlersInitialized=!1;ensureToolHandlersInitialized(){this._toolHandlersInitialized||(this._toolHandlersInitialized=!0,this.oncalltool=async(e,t)=>{let n=this._registeredTools[e.name];if(!n)throw Error(`Tool ${e.name} not found`);return n.handler(e.arguments,t)},this.onlisttools=async(e,t)=>({tools:await Promise.all(Object.entries(this._registeredTools).filter(([e,t])=>t.enabled).map(async([e,t])=>{let n={name:e,title:t.title,description:t.description,inputSchema:t.inputSchema?await Fh(t.inputSchema,`input`):{type:`object`,properties:{}}};return t.outputSchema&&(n.outputSchema=await Fh(t.outputSchema,`output`)),t.annotations&&(n.annotations=t.annotations),t._meta&&(n._meta=t._meta),n}))}))}async sendToolListChanged(e={}){this._assertInitialized(`sendToolListChanged`),await this.notification({method:`notifications/tools/list_changed`,params:e})}getHostCapabilities(){return this._hostCapabilities}getHostVersion(){return this._hostInfo}getHostContext(){return this._hostContext}get ontoolinput(){return this.getEventHandler(`toolinput`)}set ontoolinput(e){this.setEventHandler(`toolinput`,e)}get ontoolinputpartial(){return this.getEventHandler(`toolinputpartial`)}set ontoolinputpartial(e){this.setEventHandler(`toolinputpartial`,e)}get ontoolresult(){return this.getEventHandler(`toolresult`)}set ontoolresult(e){this.setEventHandler(`toolresult`,e)}get ontoolcancelled(){return this.getEventHandler(`toolcancelled`)}set ontoolcancelled(e){this.setEventHandler(`toolcancelled`,e)}get onhostcontextchanged(){return this.getEventHandler(`hostcontextchanged`)}set onhostcontextchanged(e){this.setEventHandler(`hostcontextchanged`,e)}_onteardown;get onteardown(){return this._onteardown}set onteardown(e){this.warnIfRequestHandlerReplaced(`onteardown`,this._onteardown,e),this._onteardown=e,this.replaceRequestHandler(ng,(e,t)=>{if(!this._onteardown)throw Error(`No onteardown handler set`);return this._onteardown(e.params,t)})}_oncalltool;get oncalltool(){return this._oncalltool}set oncalltool(e){this.warnIfRequestHandlerReplaced(`oncalltool`,this._oncalltool,e),this._oncalltool=e,this.replaceRequestHandler(Hp,(e,t)=>{if(!this._oncalltool)throw Error(`No oncalltool handler set`);return this._oncalltool(e.params,t)})}_onlisttools;get onlisttools(){return this._onlisttools}set onlisttools(e){this.warnIfRequestHandlerReplaced(`onlisttools`,this._onlisttools,e),this._onlisttools=e,this.replaceRequestHandler(Rp,(e,t)=>{if(!this._onlisttools)throw Error(`No onlisttools handler set`);return this._onlisttools(e.params,t)})}assertCapabilityForMethod(e){if(e===`sampling/createMessage`&&!this._hostCapabilities?.sampling)throw Error(`Host does not support sampling (required for ${e})`)}assertRequestHandlerCapability(e){switch(e){case`tools/call`:case`tools/list`:if(!this._capabilities.tools)throw Error(`Client does not support tool capability (required for ${e})`);return;case`ping`:case`ui/resource-teardown`:return;default:throw Error(`No handler for method ${e} registered`)}}assertNotificationCapability(e){}assertTaskCapability(e){throw Error(`Tasks are not supported in MCP Apps`)}assertTaskHandlerCapability(e){throw Error(`Task handlers are not supported in MCP Apps`)}async callServerTool(e,t){if(this._assertInitialized(`callServerTool`),typeof e==`string`)throw Error(`callServerTool() expects an object as its first argument, but received a string ("${e}"). Did you mean: callServerTool({ name: "${e}", arguments: { ... } })?`);return await this.request({method:`tools/call`,params:e},Bp,{onprogress:()=>{},resetTimeoutOnProgress:!0,...t})}async readServerResource(e,t){return this._assertInitialized(`readServerResource`),await this.request({method:`resources/read`,params:e},dp,t)}async listServerResources(e,t){return this._assertInitialized(`listServerResources`),await this.request({method:`resources/list`,params:e},ap,t)}async createSamplingMessage(e,t){this._assertInitialized(`createSamplingMessage`);let n=e.tools?am:im;return await this.request({method:`sampling/createMessage`,params:e},n,t)}sendMessage(e,t){return this._assertInitialized(`sendMessage`),this.request({method:`ui/message`,params:e},Jh,t)}sendLog(e){return this.notification({method:`notifications/message`,params:e})}updateModelContext(e,t){return this._assertInitialized(`updateModelContext`),this.request({method:`ui/update-model-context`,params:e},mf,t)}openLink(e,t){return this._assertInitialized(`openLink`),this.request({method:`ui/open-link`,params:e},Kh,t)}sendOpenLink=this.openLink;downloadFile(e,t){return this._assertInitialized(`downloadFile`),this.request({method:`ui/download-file`,params:e},qh,t)}requestTeardown(e={}){return this.notification({method:`ui/notifications/request-teardown`,params:e})}requestDisplayMode(e,t){return this._assertInitialized(`requestDisplayMode`),this.request({method:`ui/request-display-mode`,params:e},og,t)}sendSizeChanged(e){return this.notification({method:`ui/notifications/size-changed`,params:e})}setupSizeChangedNotifications(){let e=!1,t=0,n=0,r=()=>{e||(e=!0,requestAnimationFrame(()=>{e=!1;let r=document.documentElement,i=r.style.height;r.style.height=`max-content`;let a=Math.ceil(r.getBoundingClientRect().height);r.style.height=i;let o=Math.ceil(window.innerWidth);(o!==t||a!==n)&&(t=o,n=a,this.sendSizeChanged({width:o,height:a}))}))};r();let i=new ResizeObserver(r);return i.observe(document.documentElement),i.observe(document.body),()=>i.disconnect()}async connect(e=new Vh(window.parent,window.parent),t){if(this.transport)throw Error(`App is already connected. Call close() before connecting again.`);this._initializedSent=!1,await super.connect(e);try{let e=await this.request({method:`ui/initialize`,params:{appCapabilities:this._capabilities,appInfo:this._appInfo,protocolVersion:Bh}},dg,t);if(e===void 0)throw Error(`Server sent invalid initialize result: ${e}`);this._hostCapabilities=e.hostCapabilities,this._hostInfo=e.hostInfo,this._hostContext=e.hostContext,await this.notification({method:`ui/notifications/initialized`}),this._initializedSent=!0,this.options?.autoResize&&this.setupSizeChangedNotifications()}catch(e){throw this.close(),e}}}}));function hg(e,t){let n,r=0,i,a=()=>{n!==void 0&&(clearTimeout(n),n=void 0)},o=new pg({name:e,version:`0.0.1`},{}),s=async e=>{let t=await o.request({method:`tools/call`,params:{name:`get_generation`,arguments:{operationId:e}}},Bp);if(!t.isError)return t.structuredContent},c=(e,o)=>{n=window.setTimeout(async()=>{if(Date.now()-r>bg){t.onTimeout?.();return}try{let n=await s(e);if(n?.status===`complete`){a(),i=n,t.onResult(n);return}}catch{}c(e,Math.min(o*1.5,yg))},o)},l=e=>{e&&(a(),i=e,t.onResult(e),e.status===`running`&&e.operationId!==void 0&&(r=Date.now(),c(e.operationId,vg)))};return o.ontoolinput=()=>t.onResult({status:`running`}),o.ontoolresult=e=>l(e?.structuredContent),o.onhostcontextchanged=e=>{if(e?.theme&&Lh(e.theme),e?.styles?.variables&&Rh(e.styles.variables),e?.displayMode&&(document.documentElement.dataset.displayMode=e.displayMode),e?.safeAreaInsets){let{top:t=0,right:n=0,bottom:r=0,left:i=0}=e.safeAreaInsets;document.body.style.padding=`${t}px ${n}px ${r}px ${i}px`}},o.onteardown=async()=>(a(),{}),o.connect(new Vh(window.parent,window.parent)).catch(()=>{}),{app:o,current:()=>i}}function gg(e,t){return e.openLink({url:t})}function _g(e){let t=document.documentElement.dataset.displayMode===`fullscreen`;return e.requestDisplayMode({mode:t?`inline`:`fullscreen`}).then(e=>{e?.mode&&(document.documentElement.dataset.displayMode=e.mode)})}var $,vg,yg,bg,xg=t((()=>{mg(),Fm(),$=e=>document.getElementById(e),vg=2e3,yg=1e4,bg=36e4}));n((()=>{xg();var e=e=>{$(`status`).textContent=e};function t(e,t,n){let r=$(e);r.hidden=!t,n&&(r.title=n)}var n=hg(`Womp image`,{onTimeout:()=>e(`Still running — ask me to check on it.`),onResult:n=>{if(n.status===`running`){$(`kind`).textContent=`Working`,$(`skeleton`).classList.add(`pulsing`),$(`actions`).hidden=!0,e(`Generating…`);return}$(`skeleton`).classList.remove(`pulsing`);let r=n.previewUrl||n.imageUrl;if(r){let t=$(`hero`);t.onload=()=>{$(`skeleton`).style.display=`none`,t.style.display=`block`},t.onerror=()=>e(`Preview unavailable — the file link still works.`),t.src=r}let i=!!n.glbUrl;$(`kind`).textContent=i?`3D mesh`:`Image`,n.generationId&&($(`gid`).textContent=`#`+n.generationId,$(`gid`).hidden=!1);let a=n.glbUrl||n.imageUrl;t(`download`,!!a,i?`Download GLB`:`Open full size`),t(`expand`,!!r),$(`actions`).hidden=!a&&!r,e(``)}});$(`download`).addEventListener(`click`,()=>{let t=n.current()?.glbUrl||n.current()?.imageUrl;t&&gg(n.app,t).catch(()=>e(`Could not open the link.`))}),$(`expand`).addEventListener(`click`,()=>{_g(n.app).catch(()=>e(`This host does not support fullscreen.`))})}))();</script>
|
|
219
|
+
container holding the app. Specify either width or maxWidth, and either height or maxHeight.`),locale:A().optional().describe(`User's language and region preference in BCP 47 format.`),timeZone:A().optional().describe(`User's timezone in IANA format.`),userAgent:A().optional().describe(`Host application identifier.`),platform:L([B(`web`),B(`desktop`),B(`mobile`)]).optional().describe(`Platform type for responsive design decisions.`),deviceCapabilities:F({touch:M().optional().describe(`Whether the device supports touch input.`),hover:M().optional().describe(`Whether the device supports hover interactions.`)}).optional().describe(`Device input capabilities.`),safeAreaInsets:F({top:j().describe(`Top safe area inset in pixels.`),right:j().describe(`Right safe area inset in pixels.`),bottom:j().describe(`Bottom safe area inset in pixels.`),left:j().describe(`Left safe area inset in pixels.`)}).optional().describe(`Mobile safe area boundaries in pixels.`)}).passthrough(),ug=F({method:B(`ui/notifications/host-context-changed`),params:lg.describe(`Partial context update containing only changed fields.`)}),F({method:B(`ui/update-model-context`),params:F({content:P(jp).optional().describe(`Context content blocks (text, image, etc.).`),structuredContent:R(A(),N().describe(`Structured content for machine-readable context data.`)).optional().describe(`Structured content for machine-readable context data.`)})}),F({method:B(`ui/initialize`),params:F({appInfo:bf.describe(`App identification (name and version).`),appCapabilities:ag.describe(`Features and capabilities this app provides.`),protocolVersion:A().describe(`Protocol version this app supports.`)})}),dg=F({protocolVersion:A().describe(`Negotiated protocol version string (e.g., "2025-11-21").`),hostInfo:bf.describe(`Host application identification and version.`),hostCapabilities:ig.describe(`Features and capabilities provided by the host.`),hostContext:lg.describe(`Rich context about the host environment.`)}).passthrough(),fg={target:`draft-2020-12`},pg=class e extends zh{_appInfo;_capabilities;options;_hostCapabilities;_hostInfo;_hostContext;_registeredTools={};_initializedSent=!1;_assertInitialized(e){if(this._initializedSent)return;let t=`[ext-apps] App.${e}() called before connect() completed the ui/initialize handshake. Await app.connect() before calling this method, or move data loading to an ontoolresult handler.`;if(this.options?.strict)throw Error(t);console.warn(`${t}. This will throw in a future release.`)}eventSchemas={toolinput:Zh,toolinputpartial:Qh,toolresult:cg,toolcancelled:$h,hostcontextchanged:ug};static ONE_SHOT_EVENTS=new Set([`toolinput`,`toolinputpartial`,`toolresult`,`toolcancelled`]);_everHadListener=new Set;_assertHandlerTiming(t){if(!e.ONE_SHOT_EVENTS.has(t)||this._everHadListener.has(t)||(this._everHadListener.add(t),!this._initializedSent))return;let n=`[ext-apps] "${String(t)}" handler registered after connect() completed the ui/initialize handshake. The host may have already sent this notification. Register handlers before calling app.connect().`;if(this.options?.strict)throw Error(n);console.warn(n)}setEventHandler(e,t){t&&this._assertHandlerTiming(e),super.setEventHandler(e,t)}addEventListener(e,t){this._assertHandlerTiming(e),super.addEventListener(e,t)}onEventDispatch(e,t){e===`hostcontextchanged`&&(this._hostContext={...this._hostContext,...t})}constructor(e,t={},n={autoResize:!0}){super(n),this._appInfo=e,this._capabilities=t,this.options=n,n.allowUnsafeEval||o({jitless:!0}),this.setRequestHandler(jf,e=>(console.log(`Received ping:`,e.params),{})),this.setEventHandler(`hostcontextchanged`,void 0)}registerCapabilities(e){if(this.transport)throw Error(`Cannot register capabilities after transport is established`);this._capabilities=Dh(this._capabilities,e)}registerTool(e,t,n){if(this._registeredTools[e])throw Error(`Tool ${e} is already registered`);let r=this,i=()=>{r._initializedSent&&r._capabilities.tools?.listChanged&&r.sendToolListChanged()},a=t.inputSchema!==void 0,o={title:t.title,description:t.description,inputSchema:t.inputSchema,outputSchema:t.outputSchema,annotations:t.annotations,_meta:t._meta,enabled:!0,enable(){this.enabled=!0,i()},disable(){this.enabled=!1,i()},update(e){Object.assign(this,e),i()},remove(){r._registeredTools[e]===o&&(delete r._registeredTools[e],i())},handler:async(t,r)=>{if(!o.enabled)throw Error(`Tool ${e} is disabled`);let i;if(a){let a=o.inputSchema;i=await n(a?await Ih(a,t??{},`Invalid input for tool ${e}: `):t??{},r)}else i=await n(r);return o.outputSchema&&!i.isError&&(i.structuredContent=await Ih(o.outputSchema,i.structuredContent,`Invalid output for tool ${e}: `)),i}};return this._registeredTools[e]=o,!this._capabilities.tools&&!this.transport&&this.registerCapabilities({tools:{listChanged:!0}}),this.ensureToolHandlersInitialized(),i(),o}_toolHandlersInitialized=!1;ensureToolHandlersInitialized(){this._toolHandlersInitialized||(this._toolHandlersInitialized=!0,this.oncalltool=async(e,t)=>{let n=this._registeredTools[e.name];if(!n)throw Error(`Tool ${e.name} not found`);return n.handler(e.arguments,t)},this.onlisttools=async(e,t)=>({tools:await Promise.all(Object.entries(this._registeredTools).filter(([e,t])=>t.enabled).map(async([e,t])=>{let n={name:e,title:t.title,description:t.description,inputSchema:t.inputSchema?await Fh(t.inputSchema,`input`):{type:`object`,properties:{}}};return t.outputSchema&&(n.outputSchema=await Fh(t.outputSchema,`output`)),t.annotations&&(n.annotations=t.annotations),t._meta&&(n._meta=t._meta),n}))}))}async sendToolListChanged(e={}){this._assertInitialized(`sendToolListChanged`),await this.notification({method:`notifications/tools/list_changed`,params:e})}getHostCapabilities(){return this._hostCapabilities}getHostVersion(){return this._hostInfo}getHostContext(){return this._hostContext}get ontoolinput(){return this.getEventHandler(`toolinput`)}set ontoolinput(e){this.setEventHandler(`toolinput`,e)}get ontoolinputpartial(){return this.getEventHandler(`toolinputpartial`)}set ontoolinputpartial(e){this.setEventHandler(`toolinputpartial`,e)}get ontoolresult(){return this.getEventHandler(`toolresult`)}set ontoolresult(e){this.setEventHandler(`toolresult`,e)}get ontoolcancelled(){return this.getEventHandler(`toolcancelled`)}set ontoolcancelled(e){this.setEventHandler(`toolcancelled`,e)}get onhostcontextchanged(){return this.getEventHandler(`hostcontextchanged`)}set onhostcontextchanged(e){this.setEventHandler(`hostcontextchanged`,e)}_onteardown;get onteardown(){return this._onteardown}set onteardown(e){this.warnIfRequestHandlerReplaced(`onteardown`,this._onteardown,e),this._onteardown=e,this.replaceRequestHandler(ng,(e,t)=>{if(!this._onteardown)throw Error(`No onteardown handler set`);return this._onteardown(e.params,t)})}_oncalltool;get oncalltool(){return this._oncalltool}set oncalltool(e){this.warnIfRequestHandlerReplaced(`oncalltool`,this._oncalltool,e),this._oncalltool=e,this.replaceRequestHandler(Hp,(e,t)=>{if(!this._oncalltool)throw Error(`No oncalltool handler set`);return this._oncalltool(e.params,t)})}_onlisttools;get onlisttools(){return this._onlisttools}set onlisttools(e){this.warnIfRequestHandlerReplaced(`onlisttools`,this._onlisttools,e),this._onlisttools=e,this.replaceRequestHandler(Rp,(e,t)=>{if(!this._onlisttools)throw Error(`No onlisttools handler set`);return this._onlisttools(e.params,t)})}assertCapabilityForMethod(e){if(e===`sampling/createMessage`&&!this._hostCapabilities?.sampling)throw Error(`Host does not support sampling (required for ${e})`)}assertRequestHandlerCapability(e){switch(e){case`tools/call`:case`tools/list`:if(!this._capabilities.tools)throw Error(`Client does not support tool capability (required for ${e})`);return;case`ping`:case`ui/resource-teardown`:return;default:throw Error(`No handler for method ${e} registered`)}}assertNotificationCapability(e){}assertTaskCapability(e){throw Error(`Tasks are not supported in MCP Apps`)}assertTaskHandlerCapability(e){throw Error(`Task handlers are not supported in MCP Apps`)}async callServerTool(e,t){if(this._assertInitialized(`callServerTool`),typeof e==`string`)throw Error(`callServerTool() expects an object as its first argument, but received a string ("${e}"). Did you mean: callServerTool({ name: "${e}", arguments: { ... } })?`);return await this.request({method:`tools/call`,params:e},Bp,{onprogress:()=>{},resetTimeoutOnProgress:!0,...t})}async readServerResource(e,t){return this._assertInitialized(`readServerResource`),await this.request({method:`resources/read`,params:e},dp,t)}async listServerResources(e,t){return this._assertInitialized(`listServerResources`),await this.request({method:`resources/list`,params:e},ap,t)}async createSamplingMessage(e,t){this._assertInitialized(`createSamplingMessage`);let n=e.tools?am:im;return await this.request({method:`sampling/createMessage`,params:e},n,t)}sendMessage(e,t){return this._assertInitialized(`sendMessage`),this.request({method:`ui/message`,params:e},Jh,t)}sendLog(e){return this.notification({method:`notifications/message`,params:e})}updateModelContext(e,t){return this._assertInitialized(`updateModelContext`),this.request({method:`ui/update-model-context`,params:e},mf,t)}openLink(e,t){return this._assertInitialized(`openLink`),this.request({method:`ui/open-link`,params:e},Kh,t)}sendOpenLink=this.openLink;downloadFile(e,t){return this._assertInitialized(`downloadFile`),this.request({method:`ui/download-file`,params:e},qh,t)}requestTeardown(e={}){return this.notification({method:`ui/notifications/request-teardown`,params:e})}requestDisplayMode(e,t){return this._assertInitialized(`requestDisplayMode`),this.request({method:`ui/request-display-mode`,params:e},og,t)}sendSizeChanged(e){return this.notification({method:`ui/notifications/size-changed`,params:e})}setupSizeChangedNotifications(){let e=!1,t=0,n=0,r=()=>{e||(e=!0,requestAnimationFrame(()=>{e=!1;let r=document.documentElement,i=r.style.height;r.style.height=`max-content`;let a=Math.ceil(r.getBoundingClientRect().height);r.style.height=i;let o=Math.ceil(window.innerWidth);(o!==t||a!==n)&&(t=o,n=a,this.sendSizeChanged({width:o,height:a}))}))};r();let i=new ResizeObserver(r);return i.observe(document.documentElement),i.observe(document.body),()=>i.disconnect()}async connect(e=new Vh(window.parent,window.parent),t){if(this.transport)throw Error(`App is already connected. Call close() before connecting again.`);this._initializedSent=!1,await super.connect(e);try{let e=await this.request({method:`ui/initialize`,params:{appCapabilities:this._capabilities,appInfo:this._appInfo,protocolVersion:Bh}},dg,t);if(e===void 0)throw Error(`Server sent invalid initialize result: ${e}`);this._hostCapabilities=e.hostCapabilities,this._hostInfo=e.hostInfo,this._hostContext=e.hostContext,await this.notification({method:`ui/notifications/initialized`}),this._initializedSent=!0,this.options?.autoResize&&this.setupSizeChangedNotifications()}catch(e){throw this.close(),e}}}}));function hg(e){let t=[];return typeof e.durationSeconds==`number`&&t.push(`${e.durationSeconds.toFixed(2)}s`),e.model&&t.push(e.model),t.join(` · `)}function gg(e,t){let n,r=0,i,a=()=>{n!==void 0&&(clearTimeout(n),n=void 0)},o=new pg({name:e,version:`0.0.1`},{}),s=async e=>{let t=await o.request({method:`tools/call`,params:{name:`get_generation`,arguments:{operationId:e}}},Bp);if(!t.isError)return t.structuredContent},c=(e,o)=>{n=window.setTimeout(async()=>{if(Date.now()-r>xg){t.onTimeout?.();return}try{let n=await s(e);if(n?.status===`complete`){a(),i=n,t.onResult(n);return}}catch{}c(e,Math.min(o*1.5,bg))},o)},l=e=>{e&&(a(),i=e,t.onResult(e),e.status===`running`&&e.operationId!==void 0&&(r=Date.now(),c(e.operationId,yg)))};return o.ontoolinput=()=>t.onResult({status:`running`}),o.ontoolresult=e=>l(e?.structuredContent),o.onhostcontextchanged=e=>{if(e?.theme&&Lh(e.theme),e?.styles?.variables&&Rh(e.styles.variables),e?.displayMode&&(document.documentElement.dataset.displayMode=e.displayMode),e?.safeAreaInsets){let{top:t=0,right:n=0,bottom:r=0,left:i=0}=e.safeAreaInsets;document.body.style.padding=`${t}px ${n}px ${r}px ${i}px`}},o.onteardown=async()=>(a(),{}),o.connect(new Vh(window.parent,window.parent)).catch(()=>{}),{app:o,current:()=>i}}function _g(e,t){return e.openLink({url:t})}function vg(e){let t=document.documentElement.dataset.displayMode===`fullscreen`;return e.requestDisplayMode({mode:t?`inline`:`fullscreen`}).then(e=>{e?.mode&&(document.documentElement.dataset.displayMode=e.mode)})}var $,yg,bg,xg,Sg=t((()=>{mg(),Fm(),$=e=>document.getElementById(e),yg=2e3,bg=1e4,xg=36e4}));n((()=>{Sg();var e=e=>{$(`status`).textContent=e},t=e=>{$(`meta`).textContent=e};function n(e,t,n){let r=$(e);r.hidden=!t,n&&(r.title=n)}var r=gg(`Womp image`,{onTimeout:()=>e(`Still running — ask me to check on it.`),onResult:r=>{if(r.status===`running`){$(`skeleton`).classList.add(`pulsing`),$(`actions`).hidden=!0,t(``),e(`Generating…`);return}$(`skeleton`).classList.remove(`pulsing`);let i=r.previewUrl||r.imageUrl;if(i){let t=$(`hero`);t.onload=()=>{$(`skeleton`).style.display=`none`,t.style.display=`block`},t.onerror=()=>e(`Preview unavailable — the file link still works.`),t.src=i}let a=!!r.glbUrl;t(hg(r));let o=r.glbUrl||r.imageUrl;n(`download`,!!o,a?`Download GLB`:`Open full size`),n(`expand`,!!i),$(`actions`).hidden=!o&&!i,e(``)}});$(`download`).addEventListener(`click`,()=>{let t=r.current()?.glbUrl||r.current()?.imageUrl;t&&_g(r.app,t).catch(()=>e(`Could not open the link.`))}),$(`expand`).addEventListener(`click`,()=>{vg(r.app).catch(()=>e(`This host does not support fullscreen.`))})}))();</script>
|
|
232
220
|
</head>
|
|
233
221
|
<body>
|
|
234
222
|
<div class="card" id="card">
|
|
235
223
|
<img id="hero" class="hero" alt="" style="display: none" />
|
|
236
224
|
<div id="skeleton" class="skeleton"></div>
|
|
237
225
|
|
|
238
|
-
<div class="chips">
|
|
239
|
-
<span class="chip" id="kind">Image</span>
|
|
240
|
-
<span class="chip" id="gid" hidden></span>
|
|
241
|
-
</div>
|
|
242
|
-
|
|
243
226
|
<div class="actions" id="actions" hidden>
|
|
244
227
|
<button class="btn" id="download" title="Open full size" hidden>
|
|
245
228
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
|
|
@@ -253,6 +236,11 @@ container holding the app. Specify either width or maxWidth, and either height o
|
|
|
253
236
|
</button>
|
|
254
237
|
</div>
|
|
255
238
|
|
|
239
|
+
<!-- Two lines, not one: `meta` is what produced the result, `status` is
|
|
240
|
+
when something went wrong. Sharing an element meant a preview error
|
|
241
|
+
erased the model name, or the reverse, depending on which landed
|
|
242
|
+
last. Both collapse when empty. -->
|
|
243
|
+
<div class="meta" id="meta"></div>
|
|
256
244
|
<div class="status" id="status">Connecting…</div>
|
|
257
245
|
</div>
|
|
258
246
|
</body>
|