sbuilder-mcp 0.74.1 → 0.75.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/CHANGELOG.md CHANGED
@@ -6,6 +6,11 @@ All notable changes to this project are documented in this file.
6
6
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
7
7
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
8
8
 
9
+ ## [0.75.0] - 2026-09-28
10
+
11
+ ### Added
12
+ - `sb_review` gains a `productImages` readiness gap: since the renderer falls back to its grey `ImagePlaceholder` whenever a node has no `src`, an active product created without `images` shows that same placeholder on every card, cart line, and its own product page with nothing erroring anywhere; it counts active products with no non-empty `images` entry and fires after the pricing gaps, pointing at `sb_media_upload` (or `POST /api/media/{siteId}/from-url`) followed by a `PUT` of the product with `images: [url, …]`.
13
+
9
14
  ## [0.74.1] - 2026-09-28
10
15
 
11
16
  ### Fixed
package/CHANGELOG.vi.md CHANGED
@@ -6,6 +6,11 @@ Mọi thay đổi đáng chú ý của dự án được ghi lại trong file n
6
6
  Định dạng dựa trên [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
7
7
  và dự án tuân theo [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
8
8
 
9
+ ## [0.75.0] - 2026-09-28
10
+
11
+ ### Added
12
+ - `sb_review` có thêm gap readiness `productImages`: vì renderer dùng `ImagePlaceholder` màu xám mặc định bất cứ khi nào một node không có `src`, một sản phẩm active được tạo mà không có `images` sẽ hiện cùng ô xám đó trên mọi thẻ, mọi dòng giỏ hàng và trên chính trang sản phẩm mà không lỗi ở đâu cả; gap đếm số sản phẩm active không có mục `images` nào khác rỗng và báo sau các gap về giá, trỏ tới `sb_media_upload` (hoặc `POST /api/media/{siteId}/from-url`) rồi `PUT` lại sản phẩm với `images: [url, …]`.
13
+
9
14
  ## [0.74.1] - 2026-09-28
10
15
 
11
16
  ### Fixed
@@ -110,6 +110,9 @@ export async function gatherReadiness(ctx, siteId, pageNodes, openPageId) {
110
110
  purchasable: rows.filter((p) => (p.status ?? 'active') === 'active' && (p.priceCents ?? 0) > 0).length,
111
111
  // Drafts and archived: what a catalogue built without status:"active" is.
112
112
  inactive: rows.filter((p) => (p.status ?? 'active') !== 'active').length,
113
+ // Active and pictureless: the grey placeholder on every card.
114
+ unpictured: rows.filter((p) => (p.status ?? 'active') === 'active' &&
115
+ !(Array.isArray(p.images) && p.images.some((u) => typeof u === 'string' && u !== ''))).length,
113
116
  }
114
117
  : null;
115
118
  // A page an entity links to is that entity's own; only the shared template
@@ -558,6 +558,26 @@ export function readinessGaps(input) {
558
558
  });
559
559
  }
560
560
  }
561
+ // A CARD WITH THE PLATFORM'S GREY SQUARE WHERE THE PHOTO GOES.
562
+ //
563
+ // render/nodes/image/html.go: no src → nodes.ImagePlaceholder, "a card
564
+ // instead of a broken icon". So a product created without `images` renders
565
+ // on every card, in every drawer line and on its own page as the same grey
566
+ // placeholder — nothing errors, and a catalogue of twenty reads as a
567
+ // template nobody finished. Asked after the money questions: a store with
568
+ // no photos still takes an order.
569
+ if (input.products && input.products.active > 0 && (input.products.unpictured ?? 0) > 0) {
570
+ const n = input.products.unpictured;
571
+ gaps.push({
572
+ id: 'productImages',
573
+ draft: false,
574
+ problem: `${n} of ${input.products.active} active products have no image, so every card, cart ` +
575
+ "line and product page shows the platform's grey placeholder where the photo goes.",
576
+ fix: 'Get a picture into the library (sb_media_upload: a file, a url, or query + pick), then ' +
577
+ 'PUT the whole product back with images: [url, …] — first is the primary. POST ' +
578
+ '/api/media/{siteId}/from-url ingests straight from a url in one hop.',
579
+ });
580
+ }
561
581
  if (input.shippingMethods === 0) {
562
582
  gaps.push({
563
583
  id: 'shipping',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sbuilder-mcp",
3
- "version": "0.74.1",
3
+ "version": "0.75.0",
4
4
  "description": "MCP server that designs and operates a Store Builder site — pages, data, theme and publish — through the platform's own API and live-edit protocol.",
5
5
  "mcpName": "io.github.vuluu2k/sbuilder-mcp",
6
6
  "type": "module",