sbuilder-mcp 0.63.0 → 0.63.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 +8 -0
- package/CHANGELOG.vi.md +8 -0
- package/dist/index.js +8 -0
- package/dist/live/session.js +4 -0
- package/dist/tools/live.js +1 -1
- package/dist/tools/page.js +32 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,14 @@ 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.63.1] - 2026-09-24
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
- Live-edit frames now carry the open page's id from the moment a room is joined and whenever a new page is opened afterward, so the editor's own per-page filter no longer drops every ops, cursor, and select frame this server sends.
|
|
13
|
+
- A second `sb_live_join`, or opening a page on a different site while already in a room, now leaves the previous room instead of leaving its socket connected and reconnecting for the rest of the process.
|
|
14
|
+
- Opening a page on a site other than the one the current live room belongs to now leaves that room first, so a failed join can no longer strand the session in the wrong site's room.
|
|
15
|
+
- The server process now exits when the MCP client closes stdin, instead of being kept alive indefinitely by the live-room socket and its reconnect timer.
|
|
16
|
+
|
|
9
17
|
## [0.63.0] - 2026-09-21
|
|
10
18
|
|
|
11
19
|
### Added
|
package/CHANGELOG.vi.md
CHANGED
|
@@ -6,6 +6,14 @@ 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.63.1] - 2026-09-24
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
- Các frame live-edit giờ mang theo id của trang đang mở ngay từ lúc vào phòng và mỗi khi một trang mới được mở sau đó, để bộ lọc theo từng trang của chính editor không còn loại bỏ mọi frame ops, cursor và select mà server này gửi đi.
|
|
13
|
+
- Gọi `sb_live_join` lần thứ hai, hoặc mở một trang thuộc site khác trong khi đang ở trong một phòng, giờ sẽ rời phòng cũ thay vì để socket của nó tiếp tục kết nối và tự reconnect trong suốt phần đời còn lại của tiến trình.
|
|
14
|
+
- Mở một trang thuộc site khác với site của phòng live hiện tại giờ sẽ rời phòng đó trước, để một lần join thất bại không còn có thể khiến session bị mắc kẹt trong phòng của site sai.
|
|
15
|
+
- Tiến trình server giờ thoát khi client MCP đóng stdin, thay vì bị giữ sống vô thời hạn bởi socket của phòng live và timer reconnect của nó.
|
|
16
|
+
|
|
9
17
|
## [0.63.0] - 2026-09-21
|
|
10
18
|
|
|
11
19
|
### Added
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,14 @@ async function main() {
|
|
|
11
11
|
}
|
|
12
12
|
const server = createServer();
|
|
13
13
|
await server.connect(new StdioServerTransport());
|
|
14
|
+
// THE CLIENT CLOSED STDIN, SO THIS PROCESS IS DONE. The SDK does not exit on
|
|
15
|
+
// its own, and the live-room socket (plus its reconnect timer) keeps the event
|
|
16
|
+
// loop alive — an orphaned process that answers the server's pings, so the
|
|
17
|
+
// agent's avatar stays in the room indefinitely. Exiting closes the socket and
|
|
18
|
+
// the server publishes the leave.
|
|
19
|
+
const done = () => process.exit(0);
|
|
20
|
+
process.stdin.once('end', done);
|
|
21
|
+
process.stdin.once('close', done);
|
|
14
22
|
// stdout is the MCP channel. Every log line in this repo is console.error.
|
|
15
23
|
console.error('[sbuilder-mcp] ready on stdio');
|
|
16
24
|
}
|
package/dist/live/session.js
CHANGED
package/dist/tools/live.js
CHANGED
|
@@ -261,7 +261,7 @@ export function joinRoom(ctx, session, siteId) {
|
|
|
261
261
|
onDesync: (reason) => session.markStale(reason),
|
|
262
262
|
});
|
|
263
263
|
socket.connect();
|
|
264
|
-
session.attachLive(live);
|
|
264
|
+
session.attachLive(live, siteId);
|
|
265
265
|
}
|
|
266
266
|
export function registerLiveTools(server, ctx, session) {
|
|
267
267
|
// The page session joins on its own at the first sb_page_open. Registered
|
package/dist/tools/page.js
CHANGED
|
@@ -61,6 +61,8 @@ export class PageSession {
|
|
|
61
61
|
siteId = '';
|
|
62
62
|
pageId = '';
|
|
63
63
|
live = null;
|
|
64
|
+
/** Which site's room `live` is in — a page on another site needs another room. */
|
|
65
|
+
liveSite = '';
|
|
64
66
|
stale = null;
|
|
65
67
|
/**
|
|
66
68
|
* The document revision this session last stored, so an unchanged document is
|
|
@@ -79,8 +81,28 @@ export class PageSession {
|
|
|
79
81
|
constructor(ctx) {
|
|
80
82
|
this.ctx = ctx;
|
|
81
83
|
}
|
|
82
|
-
|
|
84
|
+
/**
|
|
85
|
+
* ONE ROOM AT A TIME. A second join (sb_live_join again, or a page on another
|
|
86
|
+
* site) used to overwrite `live` and leave the old socket reconnecting for the
|
|
87
|
+
* life of the process — a second robot in the old site's room, forever.
|
|
88
|
+
*
|
|
89
|
+
* And the page is announced HERE as well as on open: `start` was never called
|
|
90
|
+
* anywhere, so every ops/cursor/select frame went out with `pageId: ''` and
|
|
91
|
+
* the editor, which filters by page, dropped all of them.
|
|
92
|
+
*/
|
|
93
|
+
attachLive(live, siteId) {
|
|
94
|
+
if (this.live !== live)
|
|
95
|
+
this.live?.close();
|
|
83
96
|
this.live = live;
|
|
97
|
+
this.liveSite = siteId;
|
|
98
|
+
if (this.pageId && this.siteId === siteId)
|
|
99
|
+
live.start(this.pageId);
|
|
100
|
+
}
|
|
101
|
+
/** Leave the room, if in one. */
|
|
102
|
+
leaveLive() {
|
|
103
|
+
this.live?.close();
|
|
104
|
+
this.live = null;
|
|
105
|
+
this.liveSite = '';
|
|
84
106
|
}
|
|
85
107
|
/**
|
|
86
108
|
* How to open the live-edit room, handed over by `registerLiveTools`.
|
|
@@ -113,10 +135,13 @@ export class PageSession {
|
|
|
113
135
|
* rather than a new one.
|
|
114
136
|
*/
|
|
115
137
|
async ensureLive(siteId) {
|
|
116
|
-
if (this.live)
|
|
138
|
+
if (this.live && this.liveSite === siteId)
|
|
117
139
|
return 'already';
|
|
118
140
|
if (!this.liveJoiner)
|
|
119
141
|
return 'no live transport is registered';
|
|
142
|
+
// Out of the old site's room first, so a failed join below cannot leave
|
|
143
|
+
// this process sitting in a room for a site it is no longer editing.
|
|
144
|
+
this.leaveLive();
|
|
120
145
|
try {
|
|
121
146
|
this.liveJoiner(siteId);
|
|
122
147
|
return this.live ? 'joined' : 'the live transport did not attach';
|
|
@@ -314,6 +339,11 @@ export class PageSession {
|
|
|
314
339
|
// `sb_template_use` and `shareChrome` all open pages too, and a join wired to
|
|
315
340
|
// sb_page_open alone leaves every one of those editing unseen.
|
|
316
341
|
this.liveState = await this.ensureLive(siteId);
|
|
342
|
+
// Tell the room this page. A fresh join already did (attachLive); an
|
|
343
|
+
// existing one has only heard of the previous page. Without it the editor
|
|
344
|
+
// drops every frame this session sends.
|
|
345
|
+
if (this.liveState === 'already')
|
|
346
|
+
this.live?.start(pageId);
|
|
317
347
|
return this.doc.outline();
|
|
318
348
|
}
|
|
319
349
|
/** What the last open's join attempt did, for the tool that reports it. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sbuilder-mcp",
|
|
3
|
-
"version": "0.63.
|
|
3
|
+
"version": "0.63.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",
|