sbuilder-mcp 0.53.0 → 0.54.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.54.0] - 2026-09-15
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- `sb_review` reports a `mergedAuthPage` readiness gap when a single page carries two or more account forms (login, register, forgot-password, reset, or verify), since none of them then has an address a header can link to or a password-reset email can point at; the fix names `sb_store action:"form"` with a `page_name` to give each its own page.
|
|
13
|
+
|
|
9
14
|
## [0.53.0] - 2026-09-15
|
|
10
15
|
|
|
11
16
|
### Added
|
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.54.0] - 2026-09-15
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- `sb_review` giờ báo cáo lỗi sẵn sàng `mergedAuthPage` khi một trang duy nhất chứa từ hai form tài khoản trở lên (đăng nhập, đăng ký, quên mật khẩu, đặt lại, hoặc xác thực), vì khi đó không form nào có địa chỉ riêng để header liên kết tới hay để email đặt lại mật khẩu trỏ đến; hướng khắc phục nêu tên `sb_store action:"form"` kèm `page_name` để tách mỗi form ra trang riêng của nó.
|
|
13
|
+
|
|
9
14
|
## [0.53.0] - 2026-09-15
|
|
10
15
|
|
|
11
16
|
### Added
|
|
@@ -24,7 +24,7 @@ export async function gatherReadiness(ctx, siteId, pageNodes) {
|
|
|
24
24
|
}
|
|
25
25
|
};
|
|
26
26
|
const site = encodeURIComponent(siteId);
|
|
27
|
-
const [pageList, gateways, shipping, globals, productList, categoryList, pageLinks] = await Promise.all([
|
|
27
|
+
const [pageList, gateways, shipping, globals, productList, categoryList, pageLinks, formList] = await Promise.all([
|
|
28
28
|
get(`/api/sites/${site}/pages`),
|
|
29
29
|
get(`/api/sites/${site}/payment-gateways`),
|
|
30
30
|
get(`/api/sites/${site}/shipping-methods`),
|
|
@@ -42,6 +42,12 @@ export async function gatherReadiness(ctx, siteId, pageNodes) {
|
|
|
42
42
|
// right, and the rest list the whole catalogue.
|
|
43
43
|
get(`/api/sites/${site}/product-categories`),
|
|
44
44
|
get(`/api/sites/${site}/page-links`),
|
|
45
|
+
// THE FORMS, BY TYPE. A page document carries only `specials.formId` — which
|
|
46
|
+
// form a node shows, never what KIND of form it is — so nothing reading a
|
|
47
|
+
// page can tell a login form from a register form without this list. That
|
|
48
|
+
// blindness is what let one page quietly become the site's whole account
|
|
49
|
+
// area, which is the shape `mergedAuthPage` reports.
|
|
50
|
+
get(`/api/sites/${site}/forms`),
|
|
45
51
|
]);
|
|
46
52
|
// A gateway counts only when it is BOTH enabled and configured — the editor's
|
|
47
53
|
// `live` getter also filters by the store's currency, which is a narrowing:
|
|
@@ -87,5 +93,6 @@ export async function gatherReadiness(ctx, siteId, pageNodes) {
|
|
|
87
93
|
globalKinds,
|
|
88
94
|
categories,
|
|
89
95
|
categoryPageLinks,
|
|
96
|
+
forms: formList?.forms ?? null,
|
|
90
97
|
};
|
|
91
98
|
}
|
|
@@ -132,6 +132,52 @@ export function readinessGaps(input) {
|
|
|
132
132
|
'footer and a link back to the home page.',
|
|
133
133
|
});
|
|
134
134
|
}
|
|
135
|
+
// ONE PAGE QUIETLY BECAME THE WHOLE ACCOUNT AREA.
|
|
136
|
+
//
|
|
137
|
+
// This server used to tell agents, in as many words, to put the login and the
|
|
138
|
+
// register form behind a member-gate on /account. They did. The result is a
|
|
139
|
+
// page carrying two or three different jobs, and — the part that is not a
|
|
140
|
+
// matter of taste — NEITHER JOB HAS AN ADDRESS. A header can link to one
|
|
141
|
+
// thing, an email that says "reset your password" has nowhere specific to
|
|
142
|
+
// point, and a visitor who came to register meets a login form first because
|
|
143
|
+
// that is what was stacked on top.
|
|
144
|
+
//
|
|
145
|
+
// The rule was fixed; the pages it already built were not, and nothing could
|
|
146
|
+
// see them: a page document carries `specials.formId` and never the KIND of
|
|
147
|
+
// form, so only the site's own form list can tell these apart.
|
|
148
|
+
//
|
|
149
|
+
// COUNTED BY DISTINCT TYPE, not by how many form nodes there are. A form split
|
|
150
|
+
// across segments is several nodes of ONE type and is not this defect.
|
|
151
|
+
const authTypes = new Set(['login', 'register', 'forgot', 'reset', 'verify']);
|
|
152
|
+
if (input.forms && input.forms.length > 0) {
|
|
153
|
+
const typeOf = new Map(input.forms
|
|
154
|
+
.filter((f) => !!f?.id && !!f?.type)
|
|
155
|
+
.map((f) => [f.id, f.type]));
|
|
156
|
+
const onPage = new Set();
|
|
157
|
+
for (const n of input.pageNodes) {
|
|
158
|
+
if (n.data.type !== 'form')
|
|
159
|
+
continue;
|
|
160
|
+
const id = n.specials?.formId;
|
|
161
|
+
const t = typeof id === 'string' ? typeOf.get(id) : undefined;
|
|
162
|
+
if (t && authTypes.has(t))
|
|
163
|
+
onPage.add(t);
|
|
164
|
+
}
|
|
165
|
+
if (onPage.size >= 2) {
|
|
166
|
+
const named = [...onPage].sort().join(', ');
|
|
167
|
+
gaps.push({
|
|
168
|
+
id: 'mergedAuthPage',
|
|
169
|
+
draft: false,
|
|
170
|
+
problem: `This page carries ${onPage.size} different account forms (${named}). Neither has an ` +
|
|
171
|
+
'address of its own, so a header can link to only one of them, a password-reset mail ' +
|
|
172
|
+
'has nowhere specific to point, and whoever came to do the second thing meets the ' +
|
|
173
|
+
'first one stacked on top.',
|
|
174
|
+
fix: 'Give each its own page: sb_store action:"form" with template "login", "register" or ' +
|
|
175
|
+
'"forgot" and a page_name builds the form AND the page in one call. Leave /account ' +
|
|
176
|
+
'showing the profile behind a member-gate with audience "members", and a short ' +
|
|
177
|
+
'sign-in prompt LINKING to the login page behind audience "guests".',
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}
|
|
135
181
|
if (!isStore(input))
|
|
136
182
|
return gaps;
|
|
137
183
|
if (pages && !published(pages, 'checkout')) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sbuilder-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.54.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",
|