webcake-storefront-mcp 1.1.2 → 1.1.4
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/dist/changelog.json +44 -0
- package/dist/index.js +1 -1
- package/dist/install.js +58 -16
- package/dist/legal.js +1 -1
- package/dist/web-guide.js +97 -25
- package/package.json +2 -2
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"v": "1.1.4",
|
|
4
|
+
"d": "23/06/2026",
|
|
5
|
+
"type": "Added",
|
|
6
|
+
"en": "The remote landing page served by the serve command now includes a \"What's new\" section that renders a version timeline loaded from a build-time…",
|
|
7
|
+
"vi": "Trang landing của lệnh serve nay có thêm mục \"Có gì mới\" hiển thị timeline lịch sử phiên bản được tải từ file changelog.json sinh ra lúc build (từ…"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"v": "1.1.3",
|
|
11
|
+
"d": "23/06/2026",
|
|
12
|
+
"type": "Changed",
|
|
13
|
+
"en": "The install command's interactive wizard now runs a three-step flow: environment selection (prod / staging / local), authentication, then IDE…",
|
|
14
|
+
"vi": "Trình hướng dẫn tương tác của lệnh install nay chạy theo 3 bước: chọn môi trường (prod / staging / local), xác thực, rồi cấu hình IDE."
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"v": "1.1.2",
|
|
18
|
+
"d": "23/06/2026",
|
|
19
|
+
"type": "Fixed",
|
|
20
|
+
"en": "The server no longer crashes at startup in container environments built with npm ci --ignore-scripts; the better-sqlite3 native SQLite module has…",
|
|
21
|
+
"vi": "Server không còn bị crash khi khởi động trong môi trường container được build bằng npm ci --ignore-scripts; module SQLite native better-sqlite3 đã…"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"v": "1.1.1",
|
|
25
|
+
"d": "23/06/2026",
|
|
26
|
+
"type": "Added",
|
|
27
|
+
"en": "The serve command's OAuth token store now optionally uses Postgres (via DATABASE_URL) for durable persistence across restarts and shared state…",
|
|
28
|
+
"vi": "Kho lưu trữ token OAuth của lệnh serve nay hỗ trợ tùy chọn sử dụng Postgres (qua DATABASE_URL) để lưu token bền vững qua các lần khởi động lại và…"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"v": "1.1.0",
|
|
32
|
+
"d": "23/06/2026",
|
|
33
|
+
"type": "Added",
|
|
34
|
+
"en": "The serve (remote Streamable-HTTP) mode now embeds a full OAuth 2.1 Authorization Server at /authorize, /token, /revoke, /register, and…",
|
|
35
|
+
"vi": "Chế độ serve (remote Streamable-HTTP) nay tích hợp sẵn một Authorization Server OAuth 2.1 đầy đủ tại các endpoint /authorize, /token, /revoke,…"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"v": "1.0.3",
|
|
39
|
+
"d": "23/06/2026",
|
|
40
|
+
"type": "Added",
|
|
41
|
+
"en": "MIT license (Copyright vuluu2k) added to the package.",
|
|
42
|
+
"vi": "Thêm giấy phép MIT (Copyright vuluu2k) vào package."
|
|
43
|
+
}
|
|
44
|
+
]
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ Usage: npx -y webcake-storefront-mcp [command] [options]
|
|
|
8
8
|
|
|
9
9
|
Commands:
|
|
10
10
|
(none) start the stdio MCP server (use this in IDE configs)
|
|
11
|
-
install configure the server in your IDE(s) — interactive or via flags
|
|
11
|
+
install configure the server in your IDE(s) — interactive (env + browser login/token) or via flags
|
|
12
12
|
uninstall remove the server from your IDE configs
|
|
13
13
|
login grab your token via the browser (saved to the local config db)
|
|
14
14
|
serve [--port N] run the remote Streamable-HTTP server (default 8787; or PORT env)
|
package/dist/install.js
CHANGED
|
@@ -5,6 +5,7 @@ import { homedir } from "node:os";
|
|
|
5
5
|
import { dirname, join } from "node:path";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
import { createInterface } from "node:readline/promises";
|
|
8
|
+
import { runLogin } from "./auth/login.js";
|
|
8
9
|
const SERVER_KEY = "webcake-storefront";
|
|
9
10
|
function parseArgs(argv) {
|
|
10
11
|
const o = { uninstall: false, ides: [] };
|
|
@@ -100,34 +101,72 @@ function applyToIde(ide, opts, launch, env) {
|
|
|
100
101
|
writeJson(cfg.path, json);
|
|
101
102
|
return `${ide}: configured (${cfg.path})`;
|
|
102
103
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
/**
|
|
105
|
+
* Interactive wizard (TTY only): pick environment → authenticate (browser login,
|
|
106
|
+
* recommended, or paste a token) → pick IDEs. Mirrors webcake-landing-mcp's
|
|
107
|
+
* installer. Returns whether a browser login completed (token then lives in the
|
|
108
|
+
* local config db, so it is NOT written into the IDE env block).
|
|
109
|
+
*/
|
|
110
|
+
async function promptInteractive(opts) {
|
|
111
|
+
let loggedIn = false;
|
|
112
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY)
|
|
113
|
+
return { loggedIn };
|
|
106
114
|
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
107
115
|
try {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
116
|
+
// 1) Environment — drives which API/app URLs are used (default prod).
|
|
117
|
+
if (!opts.uninstall && !opts.env && !process.env.WEBCAKE_ENV) {
|
|
118
|
+
const e = (await rl.question("Environment [prod] / staging / local: ")).trim().toLowerCase();
|
|
119
|
+
if (e === "staging" || e === "local")
|
|
120
|
+
opts.env = e;
|
|
111
121
|
}
|
|
122
|
+
if (opts.env)
|
|
123
|
+
process.env.WEBCAKE_ENV = opts.env; // so the login flow opens the right app
|
|
124
|
+
// 2) Authentication — browser login (recommended) or paste a token. An explicit
|
|
125
|
+
// --token/--jwt or an ambient WEBCAKE_TOKEN skips this entirely.
|
|
112
126
|
if (!opts.uninstall && !opts.token && !process.env.WEBCAKE_TOKEN) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
127
|
+
console.error("\nHow do you want to connect your WebCake account?");
|
|
128
|
+
console.error(" 1) Log in via browser (recommended — opens WebCake, saves a token)");
|
|
129
|
+
console.error(" 2) Paste a token manually");
|
|
130
|
+
const choice = (await rl.question("Choose [1]: ")).trim() || "1";
|
|
131
|
+
if (choice === "1") {
|
|
132
|
+
try {
|
|
133
|
+
rl.pause();
|
|
134
|
+
await runLogin([]); // loopback browser flow → saves token + session to local config db
|
|
135
|
+
loggedIn = true;
|
|
136
|
+
}
|
|
137
|
+
catch (e) {
|
|
138
|
+
console.error(`Login didn't complete (${e?.message ?? e}). Paste a token now, or run \`npx -y webcake-storefront-mcp login\` later.`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (!loggedIn && choice !== "1") {
|
|
142
|
+
const t = (await rl.question(" Token (paste JWT): ")).trim();
|
|
143
|
+
if (t)
|
|
144
|
+
opts.token = t;
|
|
145
|
+
const s = (await rl.question(" Session id (x-session-id): ")).trim();
|
|
146
|
+
if (s)
|
|
147
|
+
opts.sessionId = s;
|
|
148
|
+
}
|
|
116
149
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
150
|
+
// 3) IDEs to configure.
|
|
151
|
+
if (!opts.ides.length) {
|
|
152
|
+
const ans = (await rl.question(`\nIDE(s) to configure [${ALL_IDES.join(", ")}, all]: `)).trim();
|
|
153
|
+
opts.ides = ans === "all" || ans === "" ? ALL_IDES : ans.split(",").map((s) => s.trim());
|
|
121
154
|
}
|
|
122
155
|
// Site is chosen at runtime — use the list_my_sites / switch_site tools in chat.
|
|
123
156
|
}
|
|
124
157
|
finally {
|
|
125
|
-
|
|
158
|
+
try {
|
|
159
|
+
rl.close();
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
/* already closed */
|
|
163
|
+
}
|
|
126
164
|
}
|
|
165
|
+
return { loggedIn };
|
|
127
166
|
}
|
|
128
167
|
export async function runInstaller(argv) {
|
|
129
168
|
const opts = parseArgs(argv);
|
|
130
|
-
await
|
|
169
|
+
const { loggedIn } = await promptInteractive(opts);
|
|
131
170
|
let ides = opts.ides.length ? opts.ides : ALL_IDES;
|
|
132
171
|
if (ides.includes("all"))
|
|
133
172
|
ides = ALL_IDES;
|
|
@@ -136,6 +175,9 @@ export async function runInstaller(argv) {
|
|
|
136
175
|
console.error(opts.uninstall ? "Removing webcake-storefront MCP…" : "Configuring webcake-storefront MCP…");
|
|
137
176
|
for (const ide of ides)
|
|
138
177
|
console.error(" " + applyToIde(ide, opts, launch, env));
|
|
139
|
-
if (!opts.uninstall)
|
|
178
|
+
if (!opts.uninstall) {
|
|
179
|
+
if (loggedIn)
|
|
180
|
+
console.error("\n✓ Logged in — your token is saved to the local config (no token written into IDE files).");
|
|
140
181
|
console.error("\nDone. Restart your IDE to pick up the new MCP server.");
|
|
182
|
+
}
|
|
141
183
|
}
|
package/dist/legal.js
CHANGED
|
@@ -13,7 +13,7 @@ function page(title, bodyHtml) {
|
|
|
13
13
|
<style>
|
|
14
14
|
:root{color-scheme:light dark}
|
|
15
15
|
body{margin:0;font-family:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;line-height:1.65;color:#1e293b;background:#f8fafc}
|
|
16
|
-
@media(prefers-color-scheme:dark){body{color:#
|
|
16
|
+
@media(prefers-color-scheme:dark){body{color:#eaf1ee;background:#0f1714}a{color:#6fe6c0}}
|
|
17
17
|
main{max-width:760px;margin:0 auto;padding:48px 24px 80px}
|
|
18
18
|
h1{font-size:1.9rem;margin:0 0 4px}
|
|
19
19
|
h2{font-size:1.2rem;margin:32px 0 8px}
|
package/dist/web-guide.js
CHANGED
|
@@ -14,7 +14,11 @@
|
|
|
14
14
|
*
|
|
15
15
|
* Self-contained (inline CSS + JS, no external fonts/trackers) so it loads instantly.
|
|
16
16
|
*/
|
|
17
|
-
|
|
17
|
+
import { readFileSync } from "node:fs";
|
|
18
|
+
// The SPA page (on the builder app) that shows the user their personal remote
|
|
19
|
+
// connector link with login already built in — see builderx_spa McpRemoteStore.vue
|
|
20
|
+
// (/mcp-remote-store). The raw MCP endpoint itself is {ENDPOINT} = <origin>/mcp.
|
|
21
|
+
const MCP_REMOTE_URL = "https://webcake.io/mcp-remote-store";
|
|
18
22
|
const INSTALL_CMD = "npx -y webcake-storefront-mcp install";
|
|
19
23
|
const INSTALL_ALL_CMD = "npx -y webcake-storefront-mcp install --ide all --token <TOKEN> --session <SESSION>";
|
|
20
24
|
const GITHUB_URL = "https://github.com/vuluu2k/webcake-storefront-mcp";
|
|
@@ -226,15 +230,15 @@ const T = {
|
|
|
226
230
|
'<b>Mở lại ứng dụng AI.</b> Khi thấy <code class="inl">webcake-storefront</code> xuất hiện trong danh sách công cụ là bạn đã kết nối thành công — hãy thử nói "Tạo cho tôi trang sản phẩm…"',
|
|
227
231
|
],
|
|
228
232
|
m1Note: "Muốn cài cho nhiều ứng dụng cùng lúc — dùng lệnh này:",
|
|
229
|
-
m2Tag: "Cách ② · Dùng
|
|
230
|
-
m2Sub: "Phù hợp khi bạn dùng Claude trên web (claude.ai)
|
|
233
|
+
m2Tag: "Cách ② · Dùng link — không cần cài gì",
|
|
234
|
+
m2Sub: "Phù hợp khi bạn dùng Claude trên web (claude.ai), máy không cài được phần mềm, hoặc dùng theo nhóm.",
|
|
231
235
|
m2Steps: [
|
|
232
|
-
'<b>
|
|
233
|
-
'<b>
|
|
234
|
-
"<b>Dán
|
|
235
|
-
"<b>Bấm
|
|
236
|
+
'<b>Lấy link riêng của bạn</b> (đã gắn sẵn mã đăng nhập) — mở trang dưới đây rồi bấm <b>Copy</b>:<a class="btn" href="{REMOTE}">Mở {REMOTE_HOST} {ARROW}</a>',
|
|
237
|
+
'<b>Vào nơi thêm kết nối</b> trong ứng dụng:<br>• claude.ai: <i>Settings → Connectors → Add custom connector</i><br>• Cursor / Claude Code: mở file <code class="inl">.mcp.json</code>',
|
|
238
|
+
"<b>Dán link</b> bạn vừa copy (trông giống như):<pre>{ENDPOINT}?jwt=<MÃ CỦA BẠN>&session_id=<PHIÊN CỦA BẠN></pre>",
|
|
239
|
+
"<b>Bấm Add</b> (hoặc lưu file) rồi chờ một chút. Khi biểu tượng WebCake chuyển xanh là dùng được.",
|
|
236
240
|
],
|
|
237
|
-
m2Note: "
|
|
241
|
+
m2Note: "⚠️ Link có chứa mã đăng nhập riêng của bạn — hãy coi như mật khẩu, đừng chia sẻ cho ai.",
|
|
238
242
|
toolsH2: "Trợ lý có thể giúp bạn làm gì",
|
|
239
243
|
toolsSub: "Nói chuyện bình thường với trợ lý — bạn không cần biết tên công cụ hay lệnh nào cả.",
|
|
240
244
|
toolGroups: [
|
|
@@ -278,6 +282,9 @@ const T = {
|
|
|
278
282
|
promptSub: "Bạn có thể nói tự nhiên bằng tiếng Việt. Ví dụ:",
|
|
279
283
|
promptEx: "Tạo cho tôi một trang sản phẩm trên WebCake cho thương hiệu [tên thương hiệu].\nTrang cần có: ảnh sản phẩm lớn, tên và giá, mô tả ngắn, nút \"Mua ngay\".\nKiểm tra kỹ trước khi lưu, rồi xuất bản lên cửa hàng của tôi.",
|
|
280
284
|
faqH2: "Câu hỏi thường gặp",
|
|
285
|
+
newH2: "Có gì mới",
|
|
286
|
+
newBadge: "MỚI",
|
|
287
|
+
clMore: "Xem tất cả thay đổi",
|
|
281
288
|
starH2: "Thấy hữu ích? Tặng dự án một ngôi sao nhé",
|
|
282
289
|
starP: "Đây là dự án miễn phí, mã nguồn mở — mỗi ngôi sao là một lời động viên để dự án tiếp tục phát triển và giúp nhiều người tìm ra nó hơn.",
|
|
283
290
|
starBtn: "Tặng sao trên GitHub",
|
|
@@ -289,6 +296,7 @@ const T = {
|
|
|
289
296
|
{ href: "#build", label: "Tạo được gì" },
|
|
290
297
|
{ href: "#connect", label: "Kết nối" },
|
|
291
298
|
{ href: "#tools", label: "Trợ lý làm gì" },
|
|
299
|
+
{ href: "#new", label: "Có gì mới" },
|
|
292
300
|
{ href: "#faq", label: "Hỏi đáp" },
|
|
293
301
|
],
|
|
294
302
|
},
|
|
@@ -384,15 +392,15 @@ const T = {
|
|
|
384
392
|
'<b>Reopen your AI app.</b> When you see <code class="inl">webcake-storefront</code> in the tools list, you\'re connected — try saying "Create a product page for…"',
|
|
385
393
|
],
|
|
386
394
|
m1Note: "Want to set up multiple apps at once — use this command:",
|
|
387
|
-
m2Tag: "
|
|
388
|
-
m2Sub: "Best if you use Claude on the web (claude.ai)
|
|
395
|
+
m2Tag: "Way ② · Use a link — nothing to install",
|
|
396
|
+
m2Sub: "Best if you use Claude on the web (claude.ai), can't install software, or work as a team.",
|
|
389
397
|
m2Steps: [
|
|
390
|
-
'<b>
|
|
391
|
-
'<b>Open your
|
|
392
|
-
"<b>Paste the
|
|
393
|
-
"<b>Click Add</b> (or save the file). When the WebCake icon turns
|
|
398
|
+
'<b>Get your personal link</b> (your login is built in) — open the page below and hit <b>Copy</b>:<a class="btn" href="{REMOTE}">Open {REMOTE_HOST} {ARROW}</a>',
|
|
399
|
+
'<b>Open where you add a connection</b> in your app:<br>• claude.ai: <i>Settings → Connectors → Add custom connector</i><br>• Cursor / Claude Code: open <code class="inl">.mcp.json</code>',
|
|
400
|
+
"<b>Paste the link</b> you just copied (it looks like):<pre>{ENDPOINT}?jwt=<YOUR TOKEN>&session_id=<YOUR SESSION></pre>",
|
|
401
|
+
"<b>Click Add</b> (or save the file) and wait a moment. When the WebCake icon turns green, you're good to go.",
|
|
394
402
|
],
|
|
395
|
-
m2Note: "
|
|
403
|
+
m2Note: "⚠️ This link contains your personal login — treat it like a password and don't share it.",
|
|
396
404
|
toolsH2: "What your assistant can help you do",
|
|
397
405
|
toolsSub: "Just talk to your assistant naturally — you don't need to know any tool names or commands.",
|
|
398
406
|
toolGroups: [
|
|
@@ -436,6 +444,9 @@ const T = {
|
|
|
436
444
|
promptSub: "You can speak naturally. For example:",
|
|
437
445
|
promptEx: "Create a product page on my WebCake store for [brand name].\nThe page should have: a large product image, name and price, a short description, and a \"Buy Now\" button.\nPlease check everything looks right before saving, then publish it to my store.",
|
|
438
446
|
faqH2: "Frequently asked questions",
|
|
447
|
+
newH2: "What's new",
|
|
448
|
+
newBadge: "NEW",
|
|
449
|
+
clMore: "See all changes",
|
|
439
450
|
starH2: "Find it useful? Give the project a star",
|
|
440
451
|
starP: "It's a free, open-source project — every star is a little encouragement to keep it growing and helps more people find it.",
|
|
441
452
|
starBtn: "Star on GitHub",
|
|
@@ -447,10 +458,38 @@ const T = {
|
|
|
447
458
|
{ href: "#build", label: "What you build" },
|
|
448
459
|
{ href: "#connect", label: "Connect" },
|
|
449
460
|
{ href: "#tools", label: "What it does" },
|
|
461
|
+
{ href: "#new", label: "What's new" },
|
|
450
462
|
{ href: "#faq", label: "FAQ" },
|
|
451
463
|
],
|
|
452
464
|
},
|
|
453
465
|
};
|
|
466
|
+
const CHANGELOG = loadChangelog();
|
|
467
|
+
function loadChangelog() {
|
|
468
|
+
try {
|
|
469
|
+
const raw = readFileSync(new URL("./changelog.json", import.meta.url), "utf8");
|
|
470
|
+
const data = JSON.parse(raw);
|
|
471
|
+
return Array.isArray(data) ? data : [];
|
|
472
|
+
}
|
|
473
|
+
catch {
|
|
474
|
+
return [];
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
// English Keep-a-Changelog section names → short Vietnamese tags (en uses the raw name).
|
|
478
|
+
const CL_TYPE_VI = {
|
|
479
|
+
Added: "Thêm mới",
|
|
480
|
+
Changed: "Cải tiến",
|
|
481
|
+
Fixed: "Sửa lỗi",
|
|
482
|
+
Removed: "Gỡ bỏ",
|
|
483
|
+
Deprecated: "Ngừng dùng",
|
|
484
|
+
Security: "Bảo mật",
|
|
485
|
+
Internal: "Nội bộ",
|
|
486
|
+
};
|
|
487
|
+
function clTag(type, lang) {
|
|
488
|
+
if (!type)
|
|
489
|
+
return "";
|
|
490
|
+
const label = lang === "vi" ? (CL_TYPE_VI[type] ?? "") : type;
|
|
491
|
+
return label ? ` <span class="cl-tag">${label}</span>` : "";
|
|
492
|
+
}
|
|
454
493
|
function steps(items) {
|
|
455
494
|
return items
|
|
456
495
|
.map((body, i) => `<li><span class="n">${i + 1}</span><div class="body">${body}</div></li>`)
|
|
@@ -504,8 +543,10 @@ export function guideHtml(origin, lang = "vi") {
|
|
|
504
543
|
],
|
|
505
544
|
};
|
|
506
545
|
const jsonLdScript = JSON.stringify(jsonLd).replace(/</g, "\\u003c");
|
|
546
|
+
const remoteHost = MCP_REMOTE_URL.replace("https://", "");
|
|
507
547
|
const fill = (s) => s
|
|
508
548
|
.replaceAll("{REMOTE}", MCP_REMOTE_URL)
|
|
549
|
+
.replaceAll("{REMOTE_HOST}", remoteHost)
|
|
509
550
|
.replaceAll("{ENDPOINT}", endpoint)
|
|
510
551
|
.replaceAll("{ARROW}", icon("arrow"));
|
|
511
552
|
return `<!doctype html>
|
|
@@ -546,10 +587,10 @@ export function guideHtml(origin, lang = "vi") {
|
|
|
546
587
|
:root{--g:#108B67;--g7:#0c6f52;--ink:#11121e;--mut:#5e5f7a;--bg:#f6f5ff;--card:#ffffff;
|
|
547
588
|
--line:rgba(16,14,40,.09);--shadow:0 1px 2px rgba(16,14,40,.05),0 6px 20px -12px rgba(16,14,40,.18);--code:#0e0d1a;
|
|
548
589
|
--ic-fg:#0c6f52;--btn-hover:#0c6f52;--navbg:rgba(246,245,255,.82)}
|
|
549
|
-
@media(prefers-color-scheme:dark){:root:not([data-theme="light"]){--ink:#
|
|
550
|
-
--line:rgba(255,255,255,.
|
|
551
|
-
:root[data-theme="dark"]{--ink:#
|
|
552
|
-
--line:rgba(255,255,255,.
|
|
590
|
+
@media(prefers-color-scheme:dark){:root:not([data-theme="light"]){--ink:#eaf1ee;--mut:#9fb0a9;--bg:#0f1714;--card:#18211d;
|
|
591
|
+
--line:rgba(255,255,255,.09);--shadow:0 1px 2px rgba(0,0,0,.35),0 12px 34px -16px rgba(0,0,0,.6);--code:#0b120f;--g:#16a37c;--g7:#6fe6c0;--ic-fg:#8aecc9;--btn-hover:#1cba8d;--navbg:rgba(15,23,20,.82)}}
|
|
592
|
+
:root[data-theme="dark"]{--ink:#eaf1ee;--mut:#9fb0a9;--bg:#0f1714;--card:#18211d;
|
|
593
|
+
--line:rgba(255,255,255,.09);--shadow:0 1px 2px rgba(0,0,0,.35),0 12px 34px -16px rgba(0,0,0,.6);--code:#0b120f;--g:#16a37c;--g7:#6fe6c0;--ic-fg:#8aecc9;--btn-hover:#1cba8d;--navbg:rgba(15,23,20,.82)}
|
|
553
594
|
*{box-sizing:border-box}
|
|
554
595
|
html{scroll-behavior:auto}
|
|
555
596
|
html.smooth{scroll-behavior:smooth}
|
|
@@ -605,12 +646,12 @@ export function guideHtml(origin, lang = "vi") {
|
|
|
605
646
|
text-transform:uppercase;letter-spacing:.04em;flex-wrap:wrap}
|
|
606
647
|
.tag .ic{width:30px;height:30px;border-radius:9px}
|
|
607
648
|
.tag .ic .i{width:16px;height:16px}
|
|
608
|
-
pre{margin:0;background:var(--code);color:#
|
|
649
|
+
pre{margin:0;background:var(--code);color:#e7efe9;border-radius:11px;padding:12px 14px;overflow-x:auto;
|
|
609
650
|
border:1px solid rgba(255,255,255,.06);font:600 .82rem/1.5 ui-monospace,SFMono-Regular,Menlo,monospace}
|
|
610
651
|
.codewrap{position:relative}
|
|
611
652
|
.codewrap pre{padding-right:46px}
|
|
612
653
|
.copy{position:absolute;top:8px;right:8px;width:30px;height:30px;display:grid;place-items:center;cursor:pointer;
|
|
613
|
-
border:1px solid rgba(255,255,255,.15);border-radius:8px;background:rgba(255,255,255,.06);color:#
|
|
654
|
+
border:1px solid rgba(255,255,255,.15);border-radius:8px;background:rgba(255,255,255,.06);color:#cdd8d2;
|
|
614
655
|
transition:background .15s ease,color .15s ease,border-color .15s ease}
|
|
615
656
|
.copy:hover{background:rgba(255,255,255,.13);color:#fff}
|
|
616
657
|
.copy svg{width:15px;height:15px}
|
|
@@ -699,6 +740,26 @@ export function guideHtml(origin, lang = "vi") {
|
|
|
699
740
|
display:flex;gap:18px;flex-wrap:wrap;align-items:center}
|
|
700
741
|
footer a{color:var(--g7);font-weight:600;text-decoration:none;display:inline-flex;align-items:center;gap:6px}
|
|
701
742
|
footer a:hover{text-decoration:underline}
|
|
743
|
+
.cl-wrap{padding:24px 26px 12px}
|
|
744
|
+
.cl{position:relative;margin:0;padding:0 0 0 24px;list-style:none}
|
|
745
|
+
.cl::before{content:"";position:absolute;left:6px;top:8px;bottom:14px;width:2px;
|
|
746
|
+
background:linear-gradient(var(--g),rgba(16,139,103,.08))}
|
|
747
|
+
.cl li{position:relative;padding:0 0 18px}
|
|
748
|
+
.cl li:last-child{padding-bottom:0}
|
|
749
|
+
.cl li::before{content:"";position:absolute;left:-24px;top:4px;width:12px;height:12px;border-radius:50%;
|
|
750
|
+
background:var(--card);border:2.5px solid var(--g);box-sizing:border-box}
|
|
751
|
+
.cl li.is-new::before{box-shadow:0 0 0 0 rgba(16,139,103,.5);animation:ring 2s infinite}
|
|
752
|
+
@keyframes ring{70%{box-shadow:0 0 0 8px rgba(16,139,103,0)}100%{box-shadow:0 0 0 0 rgba(16,139,103,0)}}
|
|
753
|
+
.cl .v{display:inline-flex;align-items:center;gap:8px;font-weight:800;font-size:.97rem;flex-wrap:wrap}
|
|
754
|
+
.cl-tag{font-size:.68rem;font-weight:700;color:var(--g7);background:rgba(16,139,103,.12);
|
|
755
|
+
border:1px solid var(--line);padding:1px 8px;border-radius:999px;margin-left:8px}
|
|
756
|
+
.cl .date{color:var(--mut);font-size:.79rem;margin-left:8px;font-weight:500}
|
|
757
|
+
.cl .t{color:var(--mut);font-size:.91rem;margin:3px 0 0;max-width:62ch}
|
|
758
|
+
.new{font-size:.64rem;font-weight:800;letter-spacing:.06em;color:#fff;background:var(--g);
|
|
759
|
+
padding:2px 7px;border-radius:999px;animation:blink 1.8s ease-in-out infinite}
|
|
760
|
+
@keyframes blink{50%{opacity:.55}}
|
|
761
|
+
.cl-more{display:inline-flex;align-items:center;gap:6px;margin-top:6px;font-size:.86rem;font-weight:600;color:var(--g7);text-decoration:none}
|
|
762
|
+
.cl-more:hover{gap:9px}
|
|
702
763
|
@media(max-width:640px){
|
|
703
764
|
.wrap{padding:30px 15px 56px}
|
|
704
765
|
header{flex-wrap:wrap;gap:12px}
|
|
@@ -709,6 +770,7 @@ export function guideHtml(origin, lang = "vi") {
|
|
|
709
770
|
.method{padding:18px 15px}
|
|
710
771
|
.card{padding:18px}
|
|
711
772
|
.tip{padding:11px 12px}
|
|
773
|
+
.cl-wrap{padding:18px 16px 10px}
|
|
712
774
|
.langsw{padding:6px 10px}
|
|
713
775
|
.uses li,.feat li{padding:14px}
|
|
714
776
|
.flow{flex-direction:column;align-items:stretch;overflow:visible;padding:16px}
|
|
@@ -746,7 +808,7 @@ export function guideHtml(origin, lang = "vi") {
|
|
|
746
808
|
</div>
|
|
747
809
|
</header>
|
|
748
810
|
|
|
749
|
-
<p class="hero-in" style="display:flex;gap:9px;flex-wrap:wrap"><span class="pill"><span class="dot"></span> ${t.running}</span><span class="pill">WebCake · StoreCake</span
|
|
811
|
+
<p class="hero-in" style="display:flex;gap:9px;flex-wrap:wrap"><span class="pill"><span class="dot"></span> ${t.running}</span><span class="pill">WebCake · StoreCake</span>${CHANGELOG[0] ? `<span class="pill">v${CHANGELOG[0].v}</span>` : ""}</p>
|
|
750
812
|
|
|
751
813
|
<p class="lead hero-in">${t.leadPre}<b class="grad">${t.leadGrad}</b>${t.leadPost}</p>
|
|
752
814
|
|
|
@@ -823,6 +885,16 @@ export function guideHtml(origin, lang = "vi") {
|
|
|
823
885
|
<li class="glass reveal">${tile("wand")} <span><pre style="background:transparent;color:inherit;border:none;padding:0;font-size:.88rem;white-space:pre-wrap">${t.promptEx}</pre></span></li>
|
|
824
886
|
</ul>
|
|
825
887
|
|
|
888
|
+
${CHANGELOG.length
|
|
889
|
+
? `<h2 id="new" class="reveal">${t.newH2}</h2>
|
|
890
|
+
<div class="glass cl-wrap reveal">
|
|
891
|
+
<ul class="cl">
|
|
892
|
+
${CHANGELOG.map((c, i) => `<li class="${i === 0 ? "is-new" : ""}"><span class="v">v${c.v}${i === 0 ? ` <span class="new">${t.newBadge}</span>` : ""}${clTag(c.type, L)}<span class="date">${c.d}</span></span><p class="t">${L === "en" ? c.en : c.vi}</p></li>`).join("\n ")}
|
|
893
|
+
</ul>
|
|
894
|
+
<a class="cl-more" href="${GITHUB_URL}/blob/main/${L === "en" ? "CHANGELOG.md" : "CHANGELOG.vi.md"}">${t.clMore} ${icon("arrow")}</a>
|
|
895
|
+
</div>`
|
|
896
|
+
: ""}
|
|
897
|
+
|
|
826
898
|
<h2 id="faq" class="reveal">${t.faqH2}</h2>
|
|
827
899
|
${faq.map((f) => `<details class="glass reveal"><summary>${f.q}</summary><p>${f.a}</p></details>`).join("\n ")}
|
|
828
900
|
|
|
@@ -910,7 +982,7 @@ export function ogImageSvg() {
|
|
|
910
982
|
return `<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="630" viewBox="0 0 1200 630" fill="none" font-family="system-ui,-apple-system,Segoe UI,Roboto,sans-serif">
|
|
911
983
|
<defs>
|
|
912
984
|
<linearGradient id="bg" x1="0" y1="0" x2="1200" y2="630" gradientUnits="userSpaceOnUse">
|
|
913
|
-
<stop stop-color="#
|
|
985
|
+
<stop stop-color="#0f1714"/><stop offset="1" stop-color="#0c241c"/>
|
|
914
986
|
</linearGradient>
|
|
915
987
|
<radialGradient id="glow" cx="0" cy="0" r="1" gradientTransform="translate(960 70) rotate(130) scale(620)" gradientUnits="userSpaceOnUse">
|
|
916
988
|
<stop stop-color="#108B67" stop-opacity="0.40"/><stop offset="1" stop-color="#108B67" stop-opacity="0"/>
|
|
@@ -934,12 +1006,12 @@ export function ogImageSvg() {
|
|
|
934
1006
|
<text x="90" y="300" fill="#ffffff" font-size="64" font-weight="800" letter-spacing="-2">Bạn nói điều mình muốn —</text>
|
|
935
1007
|
<text x="90" y="380" fill="#ffffff" font-size="64" font-weight="800" letter-spacing="-2">AI dựng trang, kiểm tra,</text>
|
|
936
1008
|
<text x="90" y="460" fill="#108B67" font-size="64" font-weight="800" letter-spacing="-2">đăng lên là xong.</text>
|
|
937
|
-
<text x="90" y="534" fill="#
|
|
1009
|
+
<text x="90" y="534" fill="#9fb0a9" font-size="28" font-weight="500">Không cần kéo-thả · Không cần biết lập trình · Luôn xem trước khi lưu</text>
|
|
938
1010
|
<g transform="translate(90 560)">
|
|
939
1011
|
<rect width="540" height="52" rx="12" fill="#108B67"/>
|
|
940
1012
|
<text x="270" y="34" fill="#ffffff" font-size="22" font-weight="700" text-anchor="middle">store.toolvn.io.vn</text>
|
|
941
1013
|
</g>
|
|
942
|
-
<text x="1110" y="600" fill="#
|
|
1014
|
+
<text x="1110" y="600" fill="#5a7269" font-size="22" font-weight="600" text-anchor="end">github.com/vuluu2k/webcake-storefront-mcp</text>
|
|
943
1015
|
</svg>`;
|
|
944
1016
|
}
|
|
945
1017
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "webcake-storefront-mcp",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"description": "MCP server for the WebCake/StoreCake storefront builder — page CRUD, page authoring, products, orders, and more",
|
|
5
5
|
"mcpName": "io.github.vuluu2k/webcake-storefront-mcp",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"node": ">=18"
|
|
25
25
|
},
|
|
26
26
|
"scripts": {
|
|
27
|
-
"build": "tsc && node scripts/copy-assets.mjs",
|
|
27
|
+
"build": "node scripts/gen-changelog.mjs && tsc && node scripts/copy-assets.mjs",
|
|
28
28
|
"start": "node dist/index.js",
|
|
29
29
|
"serve": "node dist/index.js serve",
|
|
30
30
|
"dev": "tsc --watch",
|