@womp/mcp-ui 0.1.6 → 0.1.8
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 +86 -2
- package/dist/index.d.ts +4 -0
- package/dist/index.js +15 -6
- package/dist/print/index.html +700 -134
- package/dist/upload/index.html +351 -0
- package/package.json +4 -3
- package/src/print/index.html +683 -117
- package/src/print/main.ts +747 -210
- package/src/print/pantone-coated.ts +5 -0
- package/src/print/pantone.ts +224 -0
- package/src/upload/index.html +277 -0
- package/src/upload/main.ts +351 -0
package/README.md
CHANGED
|
@@ -11,12 +11,14 @@ in a sandboxed iframe, pushing tool data in over postMessage.
|
|
|
11
11
|
generate_image ──► ui://womp/image-<version>.html (280 KB) image card
|
|
12
12
|
image_to_mesh ──► ui://womp/mesh-<version>.html (900 KB) 3D GLB viewer
|
|
13
13
|
get_generation ──► ui://womp/mesh-<version>.html (copes with either)
|
|
14
|
-
estimate_print ──► ui://womp/print-<version>.html (
|
|
14
|
+
estimate_print ──► ui://womp/print-<version>.html (321 KB) the print panel as a card: size, material, finish, colour, style, qty
|
|
15
15
|
prepare_print ──► ui://womp/print-<version>.html (static receipt mode)
|
|
16
16
|
add_to_cart ──► ui://womp/cart-<version>.html (260 KB) cart rows + checkout link-out
|
|
17
17
|
view_cart ──► ui://womp/cart-<version>.html (self-fills thumbnails via app-callable view_cart)
|
|
18
18
|
get_print_order ──► ui://womp/order-<version>.html (258 KB) status chips, tracking, diff-charge strip
|
|
19
19
|
list_print_orders ─► ui://womp/order-<version>.html
|
|
20
|
+
create_upload ──► ui://womp/upload-<version>.html (266 KB) drop zone: the user's mesh file goes to the ticket URL from the chat
|
|
21
|
+
get_upload ──► ui://womp/upload-<version>.html (app-callable — the card polls it)
|
|
20
22
|
```
|
|
21
23
|
|
|
22
24
|
## What it exports
|
|
@@ -30,6 +32,7 @@ const {
|
|
|
30
32
|
PRINT_APP_URI, PRINT_APP_CSP, PRINT_APP_HTML,
|
|
31
33
|
CART_APP_URI, CART_APP_CSP, CART_APP_HTML,
|
|
32
34
|
ORDER_APP_URI, ORDER_APP_CSP, ORDER_APP_HTML,
|
|
35
|
+
UPLOAD_APP_URI, UPLOAD_APP_CSP, UPLOAD_APP_HTML,
|
|
33
36
|
APP_MIME_TYPE,
|
|
34
37
|
} = require("@womp/mcp-ui");
|
|
35
38
|
```
|
|
@@ -180,6 +183,84 @@ inline (360px) so they do not wall off the transcript — which made fullscreen
|
|
|
180
183
|
useless until CSS started keying off `:root[data-display-mode="fullscreen"]`.
|
|
181
184
|
**PiP is untested.**
|
|
182
185
|
|
|
186
|
+
### The print card is the web print panel, compressed
|
|
187
|
+
|
|
188
|
+
`src/print/` follows swan-frontend's `NewPrintingPanel` step for step — Size,
|
|
189
|
+
Material (finish and colour controls inside the selection), Print style, then a
|
|
190
|
+
review row with quantity and price — so a person who has printed on womp.com
|
|
191
|
+
recognises it. Where the card differs, it is because MCP differs:
|
|
192
|
+
|
|
193
|
+
- **Size is W/H/D in cm or inches, but scales uniformly.** The tool contract
|
|
194
|
+
is `longestSideCm`, so editing one axis rescales the other two and the
|
|
195
|
+
longest side is what gets sent. The panel's 60 × 60 × 40 cm ceiling blocks the
|
|
196
|
+
button here as it does there.
|
|
197
|
+
- **Colour is a hex, snapped to Pantone.** The panel snaps a pick to the
|
|
198
|
+
nearest of 2390 Pantone coated shades and sends the code; MCP orders carry a
|
|
199
|
+
hex. The card snaps the same way (`src/print/pantone.ts`, CIEDE2000 like the
|
|
200
|
+
panel's `color-diff`) and sends the snapped shade's own hex, so both paths
|
|
201
|
+
print the same colour and show the same "Pantone 2386 C". The palette is
|
|
202
|
+
packed into `src/print/pantone-coated.ts` (28 KB) by
|
|
203
|
+
`scripts/gen-pantone.mjs <path to swan-frontend's PantoneCoatedColors.js>`;
|
|
204
|
+
regenerate it if the frontend's list changes. Colour never re-quotes — it
|
|
205
|
+
never changes the price.
|
|
206
|
+
- **Hollow never orders.** Escape holes are placed in the editor, so choosing
|
|
207
|
+
Hollow shows its price and turns the button into "Continue on womp.com",
|
|
208
|
+
which calls `prepare_print` and opens the project. The backend refuses
|
|
209
|
+
`hollow: true` outright; the card never sends it.
|
|
210
|
+
- **Gated Enterprise materials stay visible**, with a crown, behind a
|
|
211
|
+
disclosure. Tapping one keeps the current selection and shows the
|
|
212
|
+
contact-sales note (the backend's `contactUrl`) — the panel's dialog, flattened.
|
|
213
|
+
- **Tool errors are rewritten for a person.** "resin-clear-tinted is a dyed
|
|
214
|
+
material — pass a color as a #rrggbb hex" is for the model; the card says
|
|
215
|
+
"Pick a colour for this material first."
|
|
216
|
+
|
|
217
|
+
What it reads off `estimate_print` beyond the price rows: `material` (the
|
|
218
|
+
catalog KEY it sent — the backend echoes it unchanged; echoing the priced id
|
|
219
|
+
snapped Tinted clear back to Clear on every re-quote), `materialLabel`,
|
|
220
|
+
`finish`, `color`, `repaired` / `nonManifold`, and a role-aware `materials`
|
|
221
|
+
list with `swatchUrl`, `finishes`, `colorRequired` / `colorOptional`,
|
|
222
|
+
`available` and `contactUrl`.
|
|
223
|
+
|
|
224
|
+
**Layout trap that cost an hour:** a grid container's implicit `auto` track
|
|
225
|
+
grows to its items' min-content, and a bare `<input type="number">` is ~150px
|
|
226
|
+
wide intrinsically — three of them widened every row past the card's edge while
|
|
227
|
+
the card itself stayed 360px. Every grid in the card is
|
|
228
|
+
`grid-template-columns: minmax(0, 1fr)` and the inputs have `width: 0` as their
|
|
229
|
+
flex basis. If a row overflows, look there first.
|
|
230
|
+
|
|
231
|
+
The stub takes three switches for the states a default account never shows:
|
|
232
|
+
`FAKE_ENTERPRISE=1` (Enterprise materials orderable), `FAKE_PRO=1` (hollow
|
|
233
|
+
priced as available), `FAKE_REPAIRED=1` (the repaired / non-manifold callouts).
|
|
234
|
+
|
|
235
|
+
### The upload card sends bytes from inside the iframe
|
|
236
|
+
|
|
237
|
+
`src/upload/` exists because MCP has no client→server file channel and a chat
|
|
238
|
+
host's sandbox usually cannot reach Womp — so a file the user had just attached
|
|
239
|
+
to the chat could only reach the print pipeline via a womp.com page. The card
|
|
240
|
+
is that page, in the conversation: drop zone + picker, XHR `PUT` of the raw file
|
|
241
|
+
to the ticket URL swan-backend minted (`create_upload`), progress, the server's
|
|
242
|
+
own refusal text on 4xx, 409/410 terminal. It never touches the model: the
|
|
243
|
+
bytes go disk → API.
|
|
244
|
+
|
|
245
|
+
Two things outside this repo make that PUT possible, and both fail as a bare
|
|
246
|
+
network error inside the card if missing (which it turns into an "open the
|
|
247
|
+
upload page instead" button rather than a dead end):
|
|
248
|
+
|
|
249
|
+
- **`connectDomains` must name the API origin**, and the origin differs per
|
|
250
|
+
environment — so `bake-html.mjs` bakes `{}` for this card and swan-backend
|
|
251
|
+
completes the CSP with its own origin at read time. The dev stub does the
|
|
252
|
+
same with `http://localhost:3001`.
|
|
253
|
+
- **The backend answers with open CORS on `/mcp/v1/uploads`** because a
|
|
254
|
+
sandboxed iframe's origin is opaque (`Origin: null`). The ticket in the URL is
|
|
255
|
+
the security boundary, not the origin.
|
|
256
|
+
|
|
257
|
+
While pending the card polls the app-callable `get_upload`, so a file the agent
|
|
258
|
+
pushed itself (`curl -T` from a shell that has it) flips the card to done
|
|
259
|
+
instead of leaving a drop zone for a file that already landed. The dev stub
|
|
260
|
+
(`dev/server.mjs`) carries `create_upload` / `get_upload` and a `PUT
|
|
261
|
+
/mcp/v1/uploads/:token` sink with the GLB-magic sniff, so the refusal strip is
|
|
262
|
+
reachable locally too.
|
|
263
|
+
|
|
183
264
|
## Development
|
|
184
265
|
|
|
185
266
|
**Do not iterate through Claude.** A card change reaches a connector only after
|
|
@@ -212,7 +293,10 @@ It is deliberately faithful where being unfaithful would hide a bug:
|
|
|
212
293
|
| **"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) |
|
|
213
294
|
|
|
214
295
|
`FAKE_DURATION_MS=8000 yarn dev:mcp` lengthens a fake generation, so the
|
|
215
|
-
running → polling → complete transition is worth watching.
|
|
296
|
+
running → polling → complete transition is worth watching. The print stubs
|
|
297
|
+
validate like the real tools (dyed material without a colour, Enterprise
|
|
298
|
+
material, hollow intent, bad finish) so every refusal the card must render is
|
|
299
|
+
reachable locally.
|
|
216
300
|
|
|
217
301
|
**Keep the tab visible.** A backgrounded tab does not run
|
|
218
302
|
`requestAnimationFrame` and clamps `setTimeout`, so auto-resize stops reporting
|
package/dist/index.d.ts
CHANGED
|
@@ -26,3 +26,7 @@ export declare const CART_APP_HTML: string;
|
|
|
26
26
|
export declare const ORDER_APP_URI: string;
|
|
27
27
|
export declare const ORDER_APP_CSP: AppCsp;
|
|
28
28
|
export declare const ORDER_APP_HTML: string;
|
|
29
|
+
|
|
30
|
+
export declare const UPLOAD_APP_URI: string;
|
|
31
|
+
export declare const UPLOAD_APP_CSP: AppCsp;
|
|
32
|
+
export declare const UPLOAD_APP_HTML: string;
|