sbuilder-mcp 0.42.0 → 0.44.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,26 @@ 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.44.0] - 2026-09-14
10
+
11
+ ### Changed
12
+ - The live-edit socket's auth frame now names the calling harness (client, clientVersion), so the editor's presence bar and cursors can tell Claude Code, Cursor, or another agent apart instead of drawing the same robot glyph for all of them; the fields are omitted entirely when nothing identifies itself, so a client that never identified sends the exact same frame as before.
13
+
14
+ ### Fixed
15
+ - Codegen's config-value vocabulary now provably prefers a platform declaration over a renderer's own (necessarily partial) list wherever both exist for the same key, closing a precedence that was only correct by accident of loop order and could have silently flipped on the next reshuffle; pinned by a new test rather than a runtime check, since an under-report from a renderer-only key is undetectable by construction.
16
+
17
+ ## [0.43.0] - 2026-09-14
18
+
19
+ ### Added
20
+ - The catalog's legal-value vocabulary (sb_traits_for's config_values / specials_values, and sb_set's out-of-vocabulary warning) grows from 3 to 57 entries.
21
+ - spline-scene and the shared background-scene config keys on flex-section, flex-block and dataset-block now carry a full vocabulary: source/effect/gallery/speed/intensity/effectColors, including the 3D shader ids and built-in scene names read out of the runtime island.
22
+ - filter-checkbox, filter-radio, filter-color, filter-tag, select and filter-slider now carry a vocabulary for filterSource (13 values) plus the derived filterValueMode, filterMatch, filterArity and filterBehavior keys; filter-slider is correctly limited to price alone, since a range control cannot express a sort.
23
+ - Codegen now reads a fifth source directory, runtime/src, so a 3D vocabulary that only exists in the browser island is no longer invisible to the catalog; the dirty-checkout and unpublished-commit checks now cover it too.
24
+
25
+ ### Fixed
26
+ - backgroundSceneSource's vocabulary no longer omits its "model" and "spline" values; the previous release read a guard-shaped Go switch as a complete vocabulary and published only two of the key's five legal values, which would have told an agent that setting a spline scene was invalid.
27
+ - Codegen now tells a normalizing switch (which enumerates every legal value) apart from a guard switch (which only tests a subset and falls through for everything else), so a filter-shaped switch can no longer be read as a complete vocabulary.
28
+
9
29
  ## [0.42.0] - 2026-09-14
10
30
 
11
31
  ### Added
package/CHANGELOG.vi.md CHANGED
@@ -6,6 +6,26 @@ 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.44.0] - 2026-09-14
10
+
11
+ ### Changed
12
+ - Frame xác thực của socket live-edit giờ nêu rõ harness đang gọi (client, clientVersion), nhờ đó thanh presence và con trỏ của editor có thể phân biệt Claude Code, Cursor hay một agent khác thay vì vẽ chung một biểu tượng robot cho tất cả; các trường này bị bỏ qua hoàn toàn khi không có gì tự nhận diện, nên một client chưa từng tự nhận diện vẫn gửi đúng frame như trước.
13
+
14
+ ### Fixed
15
+ - Bảng giá trị config của codegen giờ chứng minh được là ưu tiên một khai báo của nền tảng hơn danh sách tự thân (vốn luôn chỉ là một phần) của renderer bất cứ khi nào cả hai cùng tồn tại cho một key, khép lại một thứ tự ưu tiên trước đây chỉ đúng nhờ tình cờ của thứ tự vòng lặp và có thể âm thầm đảo ngược ở lần sắp xếp lại kế tiếp; được ghim bằng một test mới thay vì một kiểm tra lúc chạy, vì việc báo thiếu từ một key chỉ có nguồn renderer là không thể phát hiện được về mặt cấu trúc.
16
+
17
+ ## [0.43.0] - 2026-09-14
18
+
19
+ ### Added
20
+ - Bảng giá trị hợp lệ của catalog (config_values / specials_values của sb_traits_for, và cảnh báo giá trị nằm ngoài bảng của sb_set) tăng từ 3 lên 57 mục.
21
+ - spline-scene và các config key nền cảnh 3D dùng chung trên flex-section, flex-block và dataset-block giờ có đầy đủ bảng giá trị: source/effect/gallery/speed/intensity/effectColors, bao gồm cả các id shader 3D và tên cảnh dựng sẵn đọc ra từ runtime island.
22
+ - filter-checkbox, filter-radio, filter-color, filter-tag, select và filter-slider giờ có bảng giá trị cho filterSource (13 giá trị) cùng các key dẫn xuất filterValueMode, filterMatch, filterArity và filterBehavior; filter-slider được giới hạn đúng còn mỗi price, vì một control dạng khoảng không thể diễn đạt một phép sắp xếp.
23
+ - Codegen giờ đọc thêm thư mục nguồn thứ năm, runtime/src, nhờ đó một bảng giá trị 3D chỉ tồn tại trong browser island không còn vô hình với catalog; các kiểm tra checkout-bẩn và commit-chưa-publish giờ cũng bao phủ thư mục này.
24
+
25
+ ### Fixed
26
+ - Bảng giá trị của backgroundSceneSource không còn thiếu hai giá trị "model" và "spline"; bản phát hành trước đã đọc một switch Go dạng guard như thể một bảng giá trị đầy đủ và chỉ công bố hai trong năm giá trị hợp lệ của key này, khiến một agent tưởng rằng đặt cảnh spline là không hợp lệ.
27
+ - Codegen giờ phân biệt được một switch chuẩn hóa (liệt kê đầy đủ mọi giá trị hợp lệ) với một switch dạng guard (chỉ kiểm tra một tập con rồi rơi qua nhánh mặc định cho mọi trường hợp còn lại), nhờ đó một switch dạng lọc không còn bị đọc nhầm thành một bảng giá trị đầy đủ.
28
+
9
29
  ## [0.42.0] - 2026-09-14
10
30
 
11
31
  ### Added
@@ -36876,19 +36876,6 @@ export const CONFIG_VALUES = {
36876
36876
  * the key.
36877
36877
  */
36878
36878
  export const ELEMENT_VALUES = {
36879
- "*": {
36880
- "backgroundSceneSource": {
36881
- "target": "config",
36882
- "writeKey": "backgroundSceneSource",
36883
- "values": [
36884
- "",
36885
- "effect",
36886
- "gallery"
36887
- ],
36888
- "fallback": "",
36889
- "readBy": "nodes/helpers.go:bgSceneColorRule"
36890
- }
36891
- },
36892
36879
  "media-dataset": {
36893
36880
  "mediaImageRatio": {
36894
36881
  "target": "config",
@@ -36981,6 +36968,426 @@ export const ELEMENT_VALUES = {
36981
36968
  "readBy": "nodes/tab/html.go:position"
36982
36969
  }
36983
36970
  },
36971
+ "spline-scene": {
36972
+ "source": {
36973
+ "target": "specials",
36974
+ "writeKey": "source",
36975
+ "values": [
36976
+ "effect",
36977
+ "gallery",
36978
+ "model",
36979
+ "spline"
36980
+ ],
36981
+ "readBy": "SCENE_SOURCES (schema/src/elements/spline-scene/meta.ts)"
36982
+ },
36983
+ "effect": {
36984
+ "target": "config",
36985
+ "writeKey": "effect",
36986
+ "values": [
36987
+ "aurora",
36988
+ "gradient-mesh",
36989
+ "particles",
36990
+ "waves"
36991
+ ],
36992
+ "readBy": "EFFECT_IDS (runtime/src/services/effect-shaders.ts)"
36993
+ },
36994
+ "sceneGallery": {
36995
+ "target": "specials",
36996
+ "writeKey": "sceneGallery",
36997
+ "values": [
36998
+ "card",
36999
+ "geometry",
37000
+ "gift",
37001
+ "podium",
37002
+ "sphere",
37003
+ "torus"
37004
+ ],
37005
+ "readBy": "GALLERY_CATALOGUE (runtime/src/services/gallery-scenes.ts)"
37006
+ },
37007
+ "speed": {
37008
+ "target": "config",
37009
+ "writeKey": "speed",
37010
+ "values": [
37011
+ "fast",
37012
+ "normal",
37013
+ "slow"
37014
+ ],
37015
+ "readBy": "SCENE_SPEEDS (schema/src/elements/spline-scene/meta.ts)"
37016
+ },
37017
+ "intensity": {
37018
+ "target": "config",
37019
+ "writeKey": "intensity",
37020
+ "values": [
37021
+ "normal",
37022
+ "soft",
37023
+ "strong"
37024
+ ],
37025
+ "readBy": "SCENE_INTENSITIES (schema/src/elements/spline-scene/meta.ts)"
37026
+ },
37027
+ "effectColors": {
37028
+ "target": "config",
37029
+ "writeKey": "effectColors",
37030
+ "values": [
37031
+ "custom",
37032
+ "theme"
37033
+ ],
37034
+ "readBy": "COLOR_MODES (editor/src/components/inspector/ScenePaletteRows.vue)"
37035
+ }
37036
+ },
37037
+ "*": {
37038
+ "backgroundSceneSource": {
37039
+ "target": "config",
37040
+ "writeKey": "backgroundSceneSource",
37041
+ "values": [
37042
+ "",
37043
+ "effect",
37044
+ "gallery",
37045
+ "model",
37046
+ "spline"
37047
+ ],
37048
+ "readBy": "BACKGROUND_SCENE_SOURCES (schema/src/elements/backgroundScene.ts)"
37049
+ },
37050
+ "backgroundSceneEffect": {
37051
+ "target": "config",
37052
+ "writeKey": "backgroundSceneEffect",
37053
+ "values": [
37054
+ "aurora",
37055
+ "gradient-mesh",
37056
+ "particles",
37057
+ "waves"
37058
+ ],
37059
+ "readBy": "EFFECT_IDS (runtime/src/services/effect-shaders.ts)"
37060
+ },
37061
+ "backgroundSceneGallery": {
37062
+ "target": "config",
37063
+ "writeKey": "backgroundSceneGallery",
37064
+ "values": [
37065
+ "card",
37066
+ "geometry",
37067
+ "gift",
37068
+ "podium",
37069
+ "sphere",
37070
+ "torus"
37071
+ ],
37072
+ "readBy": "GALLERY_CATALOGUE (runtime/src/services/gallery-scenes.ts)"
37073
+ },
37074
+ "backgroundSceneSpeed": {
37075
+ "target": "config",
37076
+ "writeKey": "backgroundSceneSpeed",
37077
+ "values": [
37078
+ "fast",
37079
+ "normal",
37080
+ "slow"
37081
+ ],
37082
+ "readBy": "SCENE_SPEEDS (schema/src/elements/spline-scene/meta.ts)"
37083
+ },
37084
+ "backgroundSceneIntensity": {
37085
+ "target": "config",
37086
+ "writeKey": "backgroundSceneIntensity",
37087
+ "values": [
37088
+ "normal",
37089
+ "soft",
37090
+ "strong"
37091
+ ],
37092
+ "readBy": "SCENE_INTENSITIES (schema/src/elements/spline-scene/meta.ts)"
37093
+ },
37094
+ "backgroundSceneColors": {
37095
+ "target": "config",
37096
+ "writeKey": "backgroundSceneColors",
37097
+ "values": [
37098
+ "custom",
37099
+ "theme"
37100
+ ],
37101
+ "readBy": "COLOR_MODES (editor/src/components/inspector/ScenePaletteRows.vue)"
37102
+ }
37103
+ },
37104
+ "filter-checkbox": {
37105
+ "filterSource": {
37106
+ "target": "specials",
37107
+ "writeKey": "filterSource",
37108
+ "values": [
37109
+ "attribute",
37110
+ "availability",
37111
+ "blog_category",
37112
+ "brand",
37113
+ "category",
37114
+ "course_level",
37115
+ "course_tag",
37116
+ "custom",
37117
+ "price",
37118
+ "purchase_history",
37119
+ "search",
37120
+ "sort",
37121
+ "tag"
37122
+ ],
37123
+ "readBy": "FILTER_SOURCES + SORT_SOURCE (schema/src/filters/sources.ts)"
37124
+ },
37125
+ "filterValueMode": {
37126
+ "target": "specials",
37127
+ "writeKey": "filterValueMode",
37128
+ "values": [
37129
+ "all",
37130
+ "manual"
37131
+ ],
37132
+ "readBy": "FilterConfig.valueMode (editor/src/features/filters/types.ts)"
37133
+ },
37134
+ "filterMatch": {
37135
+ "target": "specials",
37136
+ "writeKey": "filterMatch",
37137
+ "values": [
37138
+ "all",
37139
+ "any"
37140
+ ],
37141
+ "readBy": "FilterConfig.matchMode (editor/src/features/filters/types.ts)"
37142
+ },
37143
+ "filterArity": {
37144
+ "target": "specials",
37145
+ "writeKey": "filterArity",
37146
+ "values": [
37147
+ "",
37148
+ "multi",
37149
+ "single"
37150
+ ],
37151
+ "readBy": "FilterConfig.arity (editor/src/features/filters/types.ts)"
37152
+ },
37153
+ "filterBehavior": {
37154
+ "target": "specials",
37155
+ "writeKey": "filterBehavior",
37156
+ "values": [
37157
+ "event",
37158
+ "filter"
37159
+ ],
37160
+ "readBy": "FilterConfig.behavior (editor/src/features/filters/types.ts)"
37161
+ }
37162
+ },
37163
+ "filter-radio": {
37164
+ "filterSource": {
37165
+ "target": "specials",
37166
+ "writeKey": "filterSource",
37167
+ "values": [
37168
+ "attribute",
37169
+ "availability",
37170
+ "blog_category",
37171
+ "brand",
37172
+ "category",
37173
+ "course_level",
37174
+ "course_tag",
37175
+ "custom",
37176
+ "price",
37177
+ "purchase_history",
37178
+ "search",
37179
+ "sort",
37180
+ "tag"
37181
+ ],
37182
+ "readBy": "FILTER_SOURCES + SORT_SOURCE (schema/src/filters/sources.ts)"
37183
+ },
37184
+ "filterValueMode": {
37185
+ "target": "specials",
37186
+ "writeKey": "filterValueMode",
37187
+ "values": [
37188
+ "all",
37189
+ "manual"
37190
+ ],
37191
+ "readBy": "FilterConfig.valueMode (editor/src/features/filters/types.ts)"
37192
+ },
37193
+ "filterMatch": {
37194
+ "target": "specials",
37195
+ "writeKey": "filterMatch",
37196
+ "values": [
37197
+ "all",
37198
+ "any"
37199
+ ],
37200
+ "readBy": "FilterConfig.matchMode (editor/src/features/filters/types.ts)"
37201
+ },
37202
+ "filterArity": {
37203
+ "target": "specials",
37204
+ "writeKey": "filterArity",
37205
+ "values": [
37206
+ "",
37207
+ "multi",
37208
+ "single"
37209
+ ],
37210
+ "readBy": "FilterConfig.arity (editor/src/features/filters/types.ts)"
37211
+ },
37212
+ "filterBehavior": {
37213
+ "target": "specials",
37214
+ "writeKey": "filterBehavior",
37215
+ "values": [
37216
+ "event",
37217
+ "filter"
37218
+ ],
37219
+ "readBy": "FilterConfig.behavior (editor/src/features/filters/types.ts)"
37220
+ }
37221
+ },
37222
+ "filter-color": {
37223
+ "filterSource": {
37224
+ "target": "specials",
37225
+ "writeKey": "filterSource",
37226
+ "values": [
37227
+ "attribute",
37228
+ "availability",
37229
+ "blog_category",
37230
+ "brand",
37231
+ "category",
37232
+ "course_level",
37233
+ "course_tag",
37234
+ "custom",
37235
+ "price",
37236
+ "purchase_history",
37237
+ "search",
37238
+ "sort",
37239
+ "tag"
37240
+ ],
37241
+ "readBy": "FILTER_SOURCES + SORT_SOURCE (schema/src/filters/sources.ts)"
37242
+ },
37243
+ "filterValueMode": {
37244
+ "target": "specials",
37245
+ "writeKey": "filterValueMode",
37246
+ "values": [
37247
+ "all",
37248
+ "manual"
37249
+ ],
37250
+ "readBy": "FilterConfig.valueMode (editor/src/features/filters/types.ts)"
37251
+ },
37252
+ "filterMatch": {
37253
+ "target": "specials",
37254
+ "writeKey": "filterMatch",
37255
+ "values": [
37256
+ "all",
37257
+ "any"
37258
+ ],
37259
+ "readBy": "FilterConfig.matchMode (editor/src/features/filters/types.ts)"
37260
+ },
37261
+ "filterArity": {
37262
+ "target": "specials",
37263
+ "writeKey": "filterArity",
37264
+ "values": [
37265
+ "",
37266
+ "multi",
37267
+ "single"
37268
+ ],
37269
+ "readBy": "FilterConfig.arity (editor/src/features/filters/types.ts)"
37270
+ },
37271
+ "filterBehavior": {
37272
+ "target": "specials",
37273
+ "writeKey": "filterBehavior",
37274
+ "values": [
37275
+ "event",
37276
+ "filter"
37277
+ ],
37278
+ "readBy": "FilterConfig.behavior (editor/src/features/filters/types.ts)"
37279
+ }
37280
+ },
37281
+ "filter-tag": {
37282
+ "filterSource": {
37283
+ "target": "specials",
37284
+ "writeKey": "filterSource",
37285
+ "values": [
37286
+ "attribute",
37287
+ "availability",
37288
+ "blog_category",
37289
+ "brand",
37290
+ "category",
37291
+ "course_level",
37292
+ "course_tag",
37293
+ "custom",
37294
+ "price",
37295
+ "purchase_history",
37296
+ "search",
37297
+ "sort",
37298
+ "tag"
37299
+ ],
37300
+ "readBy": "FILTER_SOURCES + SORT_SOURCE (schema/src/filters/sources.ts)"
37301
+ },
37302
+ "filterValueMode": {
37303
+ "target": "specials",
37304
+ "writeKey": "filterValueMode",
37305
+ "values": [
37306
+ "all",
37307
+ "manual"
37308
+ ],
37309
+ "readBy": "FilterConfig.valueMode (editor/src/features/filters/types.ts)"
37310
+ },
37311
+ "filterMatch": {
37312
+ "target": "specials",
37313
+ "writeKey": "filterMatch",
37314
+ "values": [
37315
+ "all",
37316
+ "any"
37317
+ ],
37318
+ "readBy": "FilterConfig.matchMode (editor/src/features/filters/types.ts)"
37319
+ },
37320
+ "filterArity": {
37321
+ "target": "specials",
37322
+ "writeKey": "filterArity",
37323
+ "values": [
37324
+ "",
37325
+ "multi",
37326
+ "single"
37327
+ ],
37328
+ "readBy": "FilterConfig.arity (editor/src/features/filters/types.ts)"
37329
+ },
37330
+ "filterBehavior": {
37331
+ "target": "specials",
37332
+ "writeKey": "filterBehavior",
37333
+ "values": [
37334
+ "event",
37335
+ "filter"
37336
+ ],
37337
+ "readBy": "FilterConfig.behavior (editor/src/features/filters/types.ts)"
37338
+ }
37339
+ },
37340
+ "select": {
37341
+ "filterSource": {
37342
+ "target": "specials",
37343
+ "writeKey": "filterSource",
37344
+ "values": [
37345
+ "attribute",
37346
+ "availability",
37347
+ "blog_category",
37348
+ "brand",
37349
+ "category",
37350
+ "course_level",
37351
+ "course_tag",
37352
+ "custom",
37353
+ "price",
37354
+ "purchase_history",
37355
+ "search",
37356
+ "sort",
37357
+ "tag"
37358
+ ],
37359
+ "readBy": "FILTER_SOURCES + SORT_SOURCE (schema/src/filters/sources.ts)"
37360
+ },
37361
+ "filterBehavior": {
37362
+ "target": "specials",
37363
+ "writeKey": "filterBehavior",
37364
+ "values": [
37365
+ "event",
37366
+ "filter"
37367
+ ],
37368
+ "readBy": "FilterConfig.behavior (editor/src/features/filters/types.ts)"
37369
+ },
37370
+ "dropdown_align": {
37371
+ "target": "config",
37372
+ "writeKey": "panelAlign",
37373
+ "values": [
37374
+ "left",
37375
+ "center",
37376
+ "right"
37377
+ ],
37378
+ "readBy": "dropdown_align (editor picker)"
37379
+ }
37380
+ },
37381
+ "filter-slider": {
37382
+ "filterSource": {
37383
+ "target": "specials",
37384
+ "writeKey": "filterSource",
37385
+ "values": [
37386
+ "price"
37387
+ ],
37388
+ "readBy": "FILTER_SOURCES valueMode:\"range\" (schema/src/filters/sources.ts)"
37389
+ }
37390
+ },
36984
37391
  "cart-total": {
36985
37392
  "cart_total_part": {
36986
37393
  "target": "specials",
@@ -37125,18 +37532,6 @@ export const ELEMENT_VALUES = {
37125
37532
  "readBy": "anchored_placement (editor picker)"
37126
37533
  }
37127
37534
  },
37128
- "select": {
37129
- "dropdown_align": {
37130
- "target": "config",
37131
- "writeKey": "panelAlign",
37132
- "values": [
37133
- "left",
37134
- "center",
37135
- "right"
37136
- ],
37137
- "readBy": "dropdown_align (editor picker)"
37138
- }
37139
- },
37140
37535
  "search-keywords": {
37141
37536
  "keyword_action": {
37142
37537
  "target": "specials",
@@ -1,3 +1,12 @@
1
+ /**
2
+ * One connection to the editor's live-edit room.
3
+ *
4
+ * The browser-shaped surface narrowed to a `SocketLike` so tests can drive a
5
+ * hand-written fake — fire `onopen`, deliver a message, fire `onclose` at a
6
+ * chosen moment — with no network and no server. This is the editor's own
7
+ * testing seam, and it is why every rule below has a test rather than a comment.
8
+ */
9
+ import { agentIdentity } from './identity.js';
1
10
  /** WebSocket.OPEN per spec, as a literal so this module never reads a global. */
2
11
  const OPEN = 1;
3
12
  const RETRY_BASE_MS = 500;
@@ -39,7 +48,35 @@ export class RealtimeSocket {
39
48
  // Auth is the FIRST message, never a header (a browser cannot set one on a
40
49
  // WebSocket) and never a query parameter (a token in a URL lands in logs).
41
50
  // The server enforces a 5s deadline, so it goes out immediately.
42
- ws.send(JSON.stringify({ t: 'auth', token: this.token() }));
51
+ //
52
+ // WHICH HARNESS, because the room draws one robot for all of them.
53
+ // `identityHeaders` rides on every HTTP call and CANNOT reach this socket
54
+ // — the header door is the very one the paragraph above closes — so the
55
+ // frame carries it instead. The editor paints 🤖 for `kind === 'agent'`
56
+ // (`PresenceBar.vue`, `PeerCursors.vue`) whether the peer is Claude Code,
57
+ // Cursor or a cron job, so a merchant watching their canvas move cannot
58
+ // tell which of their tools is doing it.
59
+ //
60
+ // ADDITIVE BY CONSTRUCTION, the same property `Peer.Kind` shipped on:
61
+ // `realtime.Decode` is a plain `json.Unmarshal` with no
62
+ // `DisallowUnknownFields`, so every deployed server IGNORES these two
63
+ // today and a later one reads them without this client changing again.
64
+ // Omitted rather than sent blank when the client named nothing — a client
65
+ // that identified itself and one that did not must not look alike, which
66
+ // is the same rule `identityHeaders` follows.
67
+ //
68
+ // A LABEL AND NEVER A CLAIM. `kind` is derived server-side from the
69
+ // credential (`auth.Authorize`), which is what makes it trustworthy;
70
+ // this is asserted by the caller and must never gate anything. It is the
71
+ // same string `X-Agent-Client` already puts on every HTTP request, so the
72
+ // socket is catching up with what the platform is told regardless.
73
+ const id = agentIdentity();
74
+ ws.send(JSON.stringify({
75
+ t: 'auth',
76
+ token: this.token(),
77
+ ...(id.client ? { client: id.client } : {}),
78
+ ...(id.clientVersion ? { clientVersion: id.clientVersion } : {}),
79
+ }));
43
80
  };
44
81
  ws.onmessage = (ev) => {
45
82
  // A frame ARRIVING is the only evidence this connection is usable. An open
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sbuilder-mcp",
3
- "version": "0.42.0",
3
+ "version": "0.44.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",