sbuilder-mcp 0.4.0 → 0.4.1

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,12 @@ 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.4.1] - 2026-09-08
10
+
11
+ ### Fixed
12
+ - sb_review now reports findings inside the cart drawer and other site overlays, tagged with overlay: true, instead of silently skipping them on the belief that an overlay is not the page's to fix; the review notice explains that an overlay:true finding is fixed the same way but is site-wide, so it only needs fixing once.
13
+ - sb_api_call's path_params now matches a parameter name case-insensitively as a fallback, so a call using the common siteId spelling no longer fails against the 8 operations that spell it siteID; an exact match still wins and a genuinely missing parameter is still refused.
14
+
9
15
  ## [0.4.0] - 2026-09-08
10
16
 
11
17
  ### Added
package/CHANGELOG.vi.md CHANGED
@@ -6,6 +6,12 @@ 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.4.1] - 2026-09-08
10
+
11
+ ### Fixed
12
+ - sb_review giờ báo cáo các finding bên trong cart drawer và các overlay khác của site, gắn cờ overlay: true, thay vì âm thầm bỏ qua chúng vì cho rằng một overlay không phải trách nhiệm của trang; thông báo review giải thích rằng một finding có overlay: true được sửa theo cùng cách nhưng có phạm vi toàn site, nên chỉ cần sửa một lần.
13
+ - path_params của sb_api_call giờ khớp tên tham số không phân biệt hoa thường như một phương án dự phòng, nên một lời gọi dùng cách viết phổ biến siteId không còn thất bại với 8 operation viết là siteID; một khớp chính xác vẫn được ưu tiên và một tham số thực sự thiếu vẫn bị từ chối.
14
+
9
15
  ## [0.4.0] - 2026-09-08
10
16
 
11
17
  ### Added
@@ -12,7 +12,9 @@ import { fill } from './findings.js';
12
12
  export const REVIEW_NOTICE = 'FIX THESE. Each one is a defect a visitor will see on the published page, not a ' +
13
13
  'suggestion — a blank band, a placeholder sentence, a broken image. Apply the fix each ' +
14
14
  'finding names, then review again until the list is empty. Do not report the page as done ' +
15
- 'while findings stand; if you believe one is a false positive, say which and why.';
15
+ 'while findings stand; if you believe one is a false positive, say which and why. ' +
16
+ 'A finding marked overlay:true is in the cart drawer or a pop-up — fix it the same way ' +
17
+ '(sb_set lands there), but it is SITE-WIDE, so fix it once rather than once per page.';
16
18
  /** The specials keys an element seeds that hold its visible content. */
17
19
  function contentKeys(type) {
18
20
  const seeded = ELEMENTS[type]?.defaults.specials ?? {};
@@ -56,8 +58,19 @@ function drawsItsOwnContent(type) {
56
58
  /**
57
59
  * Everything wrong with this page that a person would notice.
58
60
  *
59
- * Overlays are skipped: the cart drawer is composed onto ROOT on read and is not
60
- * this page's to fix. So is the INSIDE of an app block (trap 5): its
61
+ * OVERLAYS ARE WALKED, and used not to be on the stated reasoning that the
62
+ * cart drawer "is not this page's to fix", which is false. An overlay's content
63
+ * reaches storage THROUGH THE PAGE SAVE (`overlays/rest/rest.go`: content is
64
+ * "deliberately NOT written here"), so `sb_set` on a drawer node lands, and the
65
+ * skip meant nothing ever reported what shipped inside one. Measured: a
66
+ * rose-and-ink storefront whose drawer carried a static mock row reading
67
+ * "Product name / 0₫", a duplicate cart list, and English copy — none of it
68
+ * mentioned by any check, on a site that reviewed clean ten pages running.
69
+ *
70
+ * Their findings carry `overlay: true`, because the master is SHARED: without
71
+ * the flag the same drawer defect reads as ten problems on a ten-page site.
72
+ *
73
+ * The INSIDE of an app block is still skipped (trap 5): its
61
74
  * placeholders are the app's, and no fix this page could apply would survive a
62
75
  * save. The block root itself is still walked — it is a node the page owns and
63
76
  * can be an empty container. Findings are ordered by document order so a caller working
@@ -84,10 +97,14 @@ export function reviewDesign(doc) {
84
97
  // itself belongs to the scope OUTSIDE it, which is why this is set before the
85
98
  // scope for the children is computed.
86
99
  const inRepeater = new Map();
87
- const go = (id, repeater) => {
88
- if (seen.has(id) || overlayIds.has(id))
100
+ // Which nodes sit inside an overlay, so their findings can say so.
101
+ const inOverlay = new Set();
102
+ const go = (id, repeater, overlay = false) => {
103
+ if (seen.has(id))
89
104
  return;
90
105
  seen.add(id);
106
+ if (overlay)
107
+ inOverlay.add(id);
91
108
  walkOrder.push(id);
92
109
  if (repeater)
93
110
  inRepeater.set(id, repeater);
@@ -95,7 +112,7 @@ export function reviewDesign(doc) {
95
112
  return;
96
113
  const inner = repeats(d.nodes[id]?.data.type ?? '') ? (repeater ?? id) : repeater;
97
114
  for (const k of childrenOf(d, id))
98
- go(k, inner);
115
+ go(k, inner, overlay || overlayIds.has(k));
99
116
  };
100
117
  go(d.root_node_id);
101
118
  for (const id of walkOrder) {
@@ -301,5 +318,12 @@ export function reviewDesign(doc) {
301
318
  }
302
319
  }
303
320
  }
321
+ // Tagged in ONE place rather than at eight push sites: whether a node sits
322
+ // inside an overlay is a fact about where it is, not about what is wrong with
323
+ // it, and threading it through every rule would put the same argument in eight
324
+ // signatures.
325
+ for (const f of out)
326
+ if (inOverlay.has(f.nodeId))
327
+ f.overlay = true;
304
328
  return out;
305
329
  }
package/dist/tools/api.js CHANGED
@@ -171,7 +171,19 @@ export async function callOperation(ctx, args) {
171
171
  let path = op.path;
172
172
  for (const m of op.path.matchAll(/\{([^}]+)\}/g)) {
173
173
  const name = m[1];
174
- const value = args.path_params?.[name];
174
+ // CASE-INSENSITIVE, because the platform spells one parameter two ways:
175
+ // `{siteId}` in 281 operations and `{siteID}` in 8. A caller who learned the
176
+ // common spelling passes the wrong key on those eight and is refused for a
177
+ // difference of one letter — a distinction no reader of the call sheet has
178
+ // any reason to notice, and one this tool has nothing to gain by enforcing.
179
+ // The exact name still wins; the fold is only a fallback.
180
+ const given = args.path_params ?? {};
181
+ let value = given[name];
182
+ if (value === undefined) {
183
+ const folded = Object.keys(given).find((k) => k.toLowerCase() === name.toLowerCase());
184
+ if (folded !== undefined)
185
+ value = given[folded];
186
+ }
175
187
  if (value === undefined) {
176
188
  // NAME THE ARGUMENT, not just the parameter. The call sheet lists these
177
189
  // under `params` while the call takes them in `path_params`, and a caller
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sbuilder-mcp",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
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",