webcake-storefront-mcp 1.24.0 → 1.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builder/attributes.js +18 -1
- package/dist/changelog.json +14 -14
- package/dist/tools/catalog-write.js +5 -2
- package/package.json +1 -1
|
@@ -289,7 +289,7 @@ export const ELEMENT_ATTRS = {
|
|
|
289
289
|
"slider-category": { specials: { showCategories: "Categories to show [{id,...}].", on_hover: "Card hover effect (zoom-in|…)." }, config: { columns: "Visible categories.", minimum_card_width: "Min card width (px).", sizeThumbnail: "{width,height} of the image.", imageBorderRadius: "Image radius.", navSize: "Arrow size (px).", arrowColor: "Arrow colour." }, events: "none" },
|
|
290
290
|
"customer-address": { events: "none", bindings: ["customer_address::full_name", "customer_address::address", "customer_address::phone_number", "customer_address::pdc", "customer_address::is_default"], notes: "Member saved addresses." },
|
|
291
291
|
wishlist: { specials: { svg: "Icon SVG.", itemCount: "Badge count." }, config: { itemCountColor: "Badge text colour.", itemBackgroundColor: "Badge background.", itemCountFontSize: "Badge size.", itemCountFontWeight: "Badge weight.", itemCountBorderRadius: "Badge radius.", itemCountFontFamily: "Badge font." }, events: "click — opens the wishlist." },
|
|
292
|
-
"favorite-icon": { events: "click — toggle favourite." },
|
|
292
|
+
"favorite-icon": { config: { mask: "Heart icon SVG mask.", colorActive: "Colour when favourited." }, events: "click — toggle favourite (add_wishlist_product / wishlist_remove_item).", notes: "Heart toggle on a product card; pairs with the wishlist element in the header." },
|
|
293
293
|
"bonus-items": { specials: { typeBonus: "combo_product | other." }, events: "none" },
|
|
294
294
|
// ── navigation ──
|
|
295
295
|
menu: { specials: { type: "horizontal | vertical | hamburger | collapse | grid | anchor.", sync: "Auto-sync items with site pages (boolean).", fullField: "Stretch items to fill the menu width (boolean).", shapeType: "'Icon' to render a hamburger/icon trigger instead of text.", url: "Icon image url (icon-style menu).", isPostList: "Build items from blog posts (boolean).", tabIndex: "Bind to a tab item." }, config: { showArrow: "Show the dropdown caret on items with a submenu (boolean).", textColor: "Item text colour (often a theme var like var(--color_20)).", colorHover: "Item hover colour.", activeColor: "Active item colour.", "--padX": "Horizontal padding inside each item (CSS var, e.g. 15px).", mask: "Icon SVG mask (icon-style menu).", arrowColor: "Caret colour.", arrowSize: "Caret size (px).", backgroundHover: "Item hover background.", borderColorHover: "Item hover border colour.", borderRadiusHover: "Item hover radius.", fontWeightHover: "Item hover font weight.", activeLink: "Active-item style object (e.g. {fontWeight:'bold'}).", maxHeight: "Max dropdown height (px)." }, events: "none", notes: "Holds menu-item children. Real headers carry TWO menus (a horizontal desktop menu + a hamburger/collapse mobile menu). Colour items via theme vars (var(--color_20))." },
|
|
@@ -321,6 +321,23 @@ export const ELEMENT_ATTRS = {
|
|
|
321
321
|
"lesson-items": { events: "none", notes: "Lessons list inside a module (course app)." },
|
|
322
322
|
"next-lesson-droppable": { events: "none", notes: "Next-lesson panel (course app)." },
|
|
323
323
|
"list-lesson-droppable": { events: "none", notes: "Lessons droppable list (course app)." },
|
|
324
|
+
// ── marketing / popups / misc widgets (rarely in page sources; built via apps/global_sources) ──
|
|
325
|
+
popup: { specials: { effect: "Open animation (fade-in|slide|…).", timeAnim: "Animation duration (s).", trigger: "When it opens: load | delay | exit_intent | scroll.", delay: "Seconds before auto-open (trigger=delay).", onlyOnce: "Show once per visitor (boolean).", overlay: "Dim the page behind (boolean)." }, config: { popupHorizontalPosition: "left | center | right.", popupVerticalPosition: "top | center | bottom." }, events: "hide — fires when the popup closes.", notes: "Modal/overlay. NOT a page section — wrap a section in a popup node and save it as a global_source (component:'popup'). Open/close from any element via events open_popup/close_popup {popup_id}. See get_build_guide → Popups." },
|
|
326
|
+
notify: { specials: { type: "Toast/banner kind.", autoClose: "Auto-dismiss (boolean).", duration: "Visible time (s)." }, events: "none", notes: "Notification / toast banner (e.g. add-to-cart confirmation). Often referenced by add_to_cart's activeNotify." },
|
|
327
|
+
"random-number": { specials: { min: "Lowest value.", max: "Highest value." }, events: "none", notes: "Displays a random number (minigame / fake-stock urgency widget)." },
|
|
328
|
+
table: { specials: { datagrid_id: "Linked data-grid id (the table's data source).", tableItems: "Column definitions [{name,key}]." }, config: { titleBackground: "Header background.", titleColor: "Header text colour.", oddBackground: "Odd-row background.", evenBackground: "Even-row background." }, events: "none", notes: "Data table bound to a data grid (specs / comparison)." },
|
|
329
|
+
"rectangle-dataset": { events: "none", bindings: ["product::product_image", "category::category_image"], notes: "A box/background bound to a dataset field (like image-dataset but a styled rectangle) — set bindings[].target." },
|
|
330
|
+
"reward-point": { specials: { ...FIELD }, config: { ...FIELD_CONFIG }, events: "none", notes: "Field to redeem loyalty reward points at checkout (member). field_name 'reward_point'." },
|
|
331
|
+
"referral-code": { specials: { field_name: "referral / referral_code.", label: FIELD.label, placeholder: FIELD.placeholder, show_label: FIELD.show_label }, config: { ...FIELD_CONFIG }, events: "none", notes: "Shows/enters a member referral code (affiliate/loyalty)." },
|
|
332
|
+
"lucky-wheel": { specials: { segments: "Wheel prizes [{label,…}].", spin_limit: "Spins allowed per user." }, events: "click — spins the wheel.", notes: "Spin-to-win minigame (marketing app)." },
|
|
333
|
+
"tee-form": { specials: { product_id: "Designable product id." }, events: "none", notes: "Print-on-demand / product-design form (apparel app)." },
|
|
334
|
+
warehouse: { specials: { warehouses: "Store/branch list [{id,name,address,…}]." }, config: { activeColor: "Selected branch colour.", hoverColor: "Hover colour.", distanceWarehouse: "Gap between branches (px)." }, events: "click — picks a pickup branch.", notes: "Store/warehouse pickup selector (checkout)." },
|
|
335
|
+
"warehouse-dataset": { events: "none", bindings: ["warehouse::name", "warehouse::address"], notes: "Warehouse/branch field bound to a dataset." },
|
|
336
|
+
calendar: { specials: { mode: "Booking view (month|week|day).", min_date: "Earliest selectable date.", max_date: "Latest selectable date." }, events: "none", notes: "Booking calendar (appointment app). Holds calendar-content." },
|
|
337
|
+
"calendar-content": { events: "none", notes: "A day/slot cell inside a calendar (appointment app)." },
|
|
338
|
+
"collapse-content": { events: "none", notes: "The expandable content panel inside a collapse-item (accordion body)." },
|
|
339
|
+
"question-container": { specials: { question_type: "single | multiple | text.", required: "Answer required (boolean)." }, events: "none", notes: "One question wrapper in a quiz/survey form (question_form)." },
|
|
340
|
+
"input-product-note": { specials: { ...FIELD }, config: { ...FIELD_CONFIG }, events: "none", notes: "Per-product note field (passes a note with the product into the cart). field_name 'product_note'." },
|
|
324
341
|
};
|
|
325
342
|
const describe = (type, key, where) => {
|
|
326
343
|
const curated = ELEMENT_ATTRS[type] || {};
|
package/dist/changelog.json
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"v": "1.26.0",
|
|
4
|
+
"d": "26/06/2026",
|
|
5
|
+
"type": "Fixed",
|
|
6
|
+
"en": "create_product now accepts a short_description parameter and sends it to the backend as [{description}] — the array shape the real product schema…",
|
|
7
|
+
"vi": "create_product nay nhận thêm tham số short_description và gửi lên backend dưới dạng [{description}] — đúng kiểu mảng mà schema sản phẩm thực tế yêu…"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"v": "1.25.0",
|
|
11
|
+
"d": "26/06/2026",
|
|
12
|
+
"type": "Changed",
|
|
13
|
+
"en": "list_elements now documents 16 previously-uncovered element types, completing curated attribute coverage across all 132 factory types: popup…",
|
|
14
|
+
"vi": "list_elements nay tài liệu hóa 16 kiểu phần tử trước đây chưa được ghi lại, hoàn thiện độ phủ thuộc tính curated cho toàn bộ 132 kiểu factory: popup…"
|
|
15
|
+
},
|
|
2
16
|
{
|
|
3
17
|
"v": "1.24.0",
|
|
4
18
|
"d": "26/06/2026",
|
|
@@ -26,19 +40,5 @@
|
|
|
26
40
|
"type": "Changed",
|
|
27
41
|
"en": "The grid-product factory now ships cross-industry neutral defaults (image_ratio:\"1/1\", gap_column/gap_row 24, products_per_load 12) instead of the…",
|
|
28
42
|
"vi": "Factory grid-product nay sử dụng các giá trị mặc định trung lập đa ngành (image_ratio:\"1/1\", gap_column/gap_row 24, products_per_load 12) thay vì…"
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
"v": "1.20.0",
|
|
32
|
-
"d": "25/06/2026",
|
|
33
|
-
"type": "Changed",
|
|
34
|
-
"en": "The header generated by scaffold_global_sections now uses a menu element with menu-item children for navigation links, matching real production…",
|
|
35
|
-
"vi": "Header được tạo bởi scaffold_global_sections nay sử dụng phần tử menu với các phần tử con menu-item cho các liên kết điều hướng, khớp với cấu trúc…"
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
"v": "1.19.1",
|
|
39
|
-
"d": "25/06/2026",
|
|
40
|
-
"type": "Fixed",
|
|
41
|
-
"en": "create_site_from_template now auto-generates a URL-safe slug from the site name when none is supplied, fixing the 400 error returned by the backend…",
|
|
42
|
-
"vi": "create_site_from_template nay tự động tạo slug an toàn cho URL từ tên site khi không có slug nào được cung cấp, khắc phục lỗi 400 mà backend trả về…"
|
|
43
43
|
}
|
|
44
44
|
]
|
|
@@ -29,14 +29,15 @@ Images must be HOSTED URLs — get them from search_images or upload_images firs
|
|
|
29
29
|
stock: z.number().default(100).describe("Stock quantity for the simple single-variation case"),
|
|
30
30
|
sku: z.string().optional().describe("SKU / custom_id for the simple case (auto-generated if omitted)"),
|
|
31
31
|
images: z.array(z.string()).optional().describe("Hosted image URLs (search_images/upload_images). First image becomes the product thumbnail."),
|
|
32
|
-
description: z.string().optional().describe("
|
|
32
|
+
description: z.string().optional().describe("Full product description (HTML allowed) — binds to product::description on the detail page."),
|
|
33
|
+
short_description: z.string().optional().describe("Short description / tagline (HTML allowed) — binds to product::short_description on cards + the detail page. Set this so cards aren't blank."),
|
|
33
34
|
category_ids: z.array(z.string()).optional().describe("Product category IDs to file the product under (from create_product_category / list_categories)"),
|
|
34
35
|
attributes: z
|
|
35
36
|
.array(z.object({ name: z.string(), values: z.array(z.string()) }))
|
|
36
37
|
.optional()
|
|
37
38
|
.describe("Variant axes, e.g. [{name:'Color',values:['Đen','Trắng']},{name:'Size',values:['S','M','L']}]"),
|
|
38
39
|
variations: z.array(variationSpec).optional().describe("Explicit per-SKU variations. Omit to auto-build one from price/stock/sku."),
|
|
39
|
-
}, ({ name, price, original_price, stock, sku, images, description, category_ids, attributes, variations }) => handle(async () => {
|
|
40
|
+
}, ({ name, price, original_price, stock, sku, images, description, short_description, category_ids, attributes, variations }) => handle(async () => {
|
|
40
41
|
let vars = variations;
|
|
41
42
|
if (!vars || !vars.length) {
|
|
42
43
|
if (price == null)
|
|
@@ -76,6 +77,8 @@ Images must be HOSTED URLs — get them from search_images or upload_images firs
|
|
|
76
77
|
ribbons: [],
|
|
77
78
|
product_attributes: attributes || [],
|
|
78
79
|
...(description ? { description } : {}),
|
|
80
|
+
// short_description is an ARRAY of {description} blocks on the real product shape.
|
|
81
|
+
...(short_description ? { short_description: [{ description: short_description }] } : {}),
|
|
79
82
|
...(images && images.length ? { image: images[0] } : {}),
|
|
80
83
|
};
|
|
81
84
|
const res = await api.createProduct(productParams);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "webcake-storefront-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.26.0",
|
|
4
4
|
"description": "MCP server for the WebCake/StoreCake storefront builder — page CRUD, page authoring, products, orders, and more",
|
|
5
5
|
"mcpName": "io.github.vuluu2k/webcake-storefront-mcp",
|
|
6
6
|
"license": "MIT",
|