sbuilder-mcp 0.50.0 → 0.51.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 +5 -0
- package/CHANGELOG.vi.md +5 -0
- package/dist/domains/site/inventory.js +84 -0
- package/dist/tools/page.js +28 -7
- package/package.json +1 -1
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.51.0] - 2026-09-15
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- `sb_page_list` now reports which of the pages most sites carry — login, register, forgot-password, contact, about, and policy pages — this site appears to be missing, matched by name against untyped `page` rows since none of them has a page type of its own, alongside a note naming the suggestion as advice rather than a defect.
|
|
13
|
+
|
|
9
14
|
## [0.50.0] - 2026-09-15
|
|
10
15
|
|
|
11
16
|
### Changed
|
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.51.0] - 2026-09-15
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- `sb_page_list` giờ báo cáo site này có vẻ đang thiếu những trang mà hầu hết các site thường có — đăng nhập, đăng ký, quên mật khẩu, liên hệ, giới thiệu và các trang chính sách — bằng cách so khớp theo tên với các trang loại `page` không có kiểu riêng, kèm ghi chú nói rõ đây là gợi ý chứ không phải lỗi.
|
|
13
|
+
|
|
9
14
|
## [0.50.0] - 2026-09-15
|
|
10
15
|
|
|
11
16
|
### Changed
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE PAGES A SITE HAS THAT THE PLATFORM CANNOT NAME.
|
|
3
|
+
*
|
|
4
|
+
* `readinessGaps` already reports every page the storefront ROUTES BY TYPE —
|
|
5
|
+
* product, category, search, checkout, complete, account, error. Each of those
|
|
6
|
+
* has a named consequence when it is absent, which is what makes it a defect.
|
|
7
|
+
*
|
|
8
|
+
* The rest of a website has no type at all. Login, register, forgot-password,
|
|
9
|
+
* contact, about and the policies are ordinary pages of type "page", so nothing
|
|
10
|
+
* anywhere can tell a site that has them from a site that does not — and an
|
|
11
|
+
* agent building a store therefore ships whatever it happened to think of. A
|
|
12
|
+
* store built with these tools came out with a home page, a product list and a
|
|
13
|
+
* category grid, and no way to contact the shop, no policy a shopper could
|
|
14
|
+
* read, and no /login for its own header to link to.
|
|
15
|
+
*
|
|
16
|
+
* ADVICE, NOT A DEFECT, AND IT SAYS SO. `readinessGaps` is a list of things
|
|
17
|
+
* that are broken; this is a list of things that are usually there. They are
|
|
18
|
+
* kept apart deliberately: a check that reports a judgement as a defect is one
|
|
19
|
+
* an author learns to ignore, and readiness.ts's own header says exactly that.
|
|
20
|
+
*
|
|
21
|
+
* MATCHED BY NAME, WHICH IS A GUESS, AND THE RESULT SAYS SO. There is no type,
|
|
22
|
+
* no flag and no API that identifies a contact page, so the only signal is what
|
|
23
|
+
* the merchant called it. A page under an unusual name therefore reads as
|
|
24
|
+
* absent. That fails in the safe direction — a line of advice about a page you
|
|
25
|
+
* already have costs a sentence; the reverse ships a shop nobody can reach.
|
|
26
|
+
*/
|
|
27
|
+
export const USUAL_PAGES = [
|
|
28
|
+
{
|
|
29
|
+
key: 'login',
|
|
30
|
+
match: ['login', 'signin', 'sign-in', 'dang-nhap', 'đăng nhập'],
|
|
31
|
+
why: 'Nothing for a header, an order email or /account\'s signed-out state to link to. ' +
|
|
32
|
+
'Seed it with sb_store action:"form" template "login" on a page of type "page".',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
key: 'register',
|
|
36
|
+
match: ['register', 'signup', 'sign-up', 'dang-ky', 'đăng ký'],
|
|
37
|
+
why: 'A shopper cannot open an account, so order history, addresses and any member-gated ' +
|
|
38
|
+
'page are unreachable. Template "register".',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
key: 'forgot',
|
|
42
|
+
match: ['forgot', 'reset', 'quen-mat-khau', 'quên mật khẩu', 'doi-mat-khau'],
|
|
43
|
+
why: 'A customer who forgets a password has no way back in and writes to support instead. ' +
|
|
44
|
+
'Template "forgot".',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
key: 'contact',
|
|
48
|
+
match: ['contact', 'lien-he', 'liên hệ'],
|
|
49
|
+
why: 'No address, phone or form anywhere, so a shopper with a question about an order has ' +
|
|
50
|
+
'nowhere to put it. Template "contact".',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
key: 'about',
|
|
54
|
+
match: ['about', 'gioi-thieu', 'giới thiệu', 've-chung-toi'],
|
|
55
|
+
why: 'Nothing says who the shop is, which is the page a first-time buyer opens before paying.',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
key: 'policy',
|
|
59
|
+
match: [
|
|
60
|
+
'policy', 'policies', 'chinh-sach', 'chính sách', 'dieu-khoan', 'điều khoản',
|
|
61
|
+
'terms', 'privacy', 'bao-mat', 'bảo mật', 'doi-tra', 'đổi trả', 'return',
|
|
62
|
+
'shipping', 'van-chuyen', 'vận chuyển', 'giao-hang', 'giao hàng', 'refund',
|
|
63
|
+
],
|
|
64
|
+
why: 'No delivery, return or privacy terms a shopper can read before paying — the pages a ' +
|
|
65
|
+
'marketplace and a payment provider both ask for.',
|
|
66
|
+
},
|
|
67
|
+
];
|
|
68
|
+
/**
|
|
69
|
+
* Which of the usual pages this site appears not to have.
|
|
70
|
+
*
|
|
71
|
+
* Only `page`-typed rows are searched: a product TEMPLATE named "Chi tiết sản
|
|
72
|
+
* phẩm" is not an about page, and letting a template satisfy one of these would
|
|
73
|
+
* report a site as complete on the strength of a page that answers a different
|
|
74
|
+
* address entirely.
|
|
75
|
+
*/
|
|
76
|
+
export function missingUsualPages(pages) {
|
|
77
|
+
if (!pages)
|
|
78
|
+
return [];
|
|
79
|
+
const hay = pages
|
|
80
|
+
.filter((p) => (typeof p.type === 'string' ? p.type === 'page' : true))
|
|
81
|
+
.map((p) => `${typeof p.slug === 'string' ? p.slug : ''} ${typeof p.name === 'string' ? p.name : ''}`.toLowerCase())
|
|
82
|
+
.join('\n');
|
|
83
|
+
return USUAL_PAGES.filter((u) => !u.match.some((m) => hay.includes(m)));
|
|
84
|
+
}
|
package/dist/tools/page.js
CHANGED
|
@@ -20,6 +20,7 @@ import { readinessGaps, READINESS_NOTICE } from '../domains/site/readiness.js';
|
|
|
20
20
|
import { gatherReadiness } from '../domains/site/readiness-fetch.js';
|
|
21
21
|
import { globalWarning, restampPatches, RESPONSIVE_NOTICE } from '../domains/site/traps.js';
|
|
22
22
|
import { catalogBrowse, catalogMatches, traitsFor } from '../catalog/element-search.js';
|
|
23
|
+
import { missingUsualPages } from '../domains/site/inventory.js';
|
|
23
24
|
import { LAYOUT_PATTERNS, PATTERN_BY_ID, THEME_TOKENS, } from '../domains/site/patterns.js';
|
|
24
25
|
import { tokensFromPage } from '../domains/site/importmap.js';
|
|
25
26
|
import { middleEnd } from '../domains/site/traps.js';
|
|
@@ -1159,13 +1160,33 @@ export function registerPageTools(server, ctx) {
|
|
|
1159
1160
|
description: "Every page on the site, with its slug and whether it is live.",
|
|
1160
1161
|
inputSchema: { site_id: z.string().optional() },
|
|
1161
1162
|
annotations: { readOnlyHint: true },
|
|
1162
|
-
}, async ({ site_id: given }) =>
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1163
|
+
}, async ({ site_id: given }) => {
|
|
1164
|
+
const raw = (await request({
|
|
1165
|
+
base: ctx.base,
|
|
1166
|
+
method: 'GET',
|
|
1167
|
+
path: `/api/sites/${encodeURIComponent(siteFor(ctx, given))}/pages`,
|
|
1168
|
+
token: siteToken(ctx),
|
|
1169
|
+
fetchImpl: ctx.fetchImpl,
|
|
1170
|
+
}));
|
|
1171
|
+
// WHAT A SITE USUALLY ALSO HAS, said where an agent is orienting rather
|
|
1172
|
+
// than after it has finished. sb_review reports the pages the storefront
|
|
1173
|
+
// ROUTES BY TYPE; these have no type at all — login, register, forgot,
|
|
1174
|
+
// contact, about, the policies are ordinary "page" rows — so nothing else
|
|
1175
|
+
// in this server can tell a site that has them from one that does not.
|
|
1176
|
+
// See ./inventory.ts: advice, matched by name, and the note says both.
|
|
1177
|
+
const missing = missingUsualPages(raw.pages ?? null);
|
|
1178
|
+
return text({
|
|
1179
|
+
...projectList(raw, 'pages', PAGE_FIELDS),
|
|
1180
|
+
...(missing.length
|
|
1181
|
+
? {
|
|
1182
|
+
usually_also: Object.fromEntries(missing.map((m) => [m.key, m.why])),
|
|
1183
|
+
usually_also_note: 'Pages most sites have that this one appears not to, found by NAME because they ' +
|
|
1184
|
+
'have no type — one you named unusually will show here anyway. Advice, not ' +
|
|
1185
|
+
'defects: sb_review reports the pages the storefront routes by type.',
|
|
1186
|
+
}
|
|
1187
|
+
: {}),
|
|
1188
|
+
});
|
|
1189
|
+
});
|
|
1169
1190
|
server.registerTool('sb_page_create', {
|
|
1170
1191
|
description: `A store type (${seededTypes().join(', ')}) arrives with the document the editor ` +
|
|
1171
1192
|
'gives a merchant — product carries the whole bound buy box; seed:false for blank. ' +
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sbuilder-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.51.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",
|