sbuilder-mcp 0.1.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 +27 -0
- package/LICENSE +21 -0
- package/README.md +142 -0
- package/README.vi.md +137 -0
- package/dist/catalog/api.generated.js +11938 -0
- package/dist/catalog/element-types.js +1 -0
- package/dist/catalog/elements.generated.js +14761 -0
- package/dist/catalog/search.js +87 -0
- package/dist/catalog/types.js +1 -0
- package/dist/core/patch.js +110 -0
- package/dist/core/tree.js +69 -0
- package/dist/domains/site/builder.js +224 -0
- package/dist/domains/site/document.js +112 -0
- package/dist/domains/site/ids.js +27 -0
- package/dist/domains/site/node.js +43 -0
- package/dist/domains/site/review.js +141 -0
- package/dist/domains/site/traps.js +98 -0
- package/dist/domains/site/validate.js +49 -0
- package/dist/index.js +20 -0
- package/dist/install/index.js +108 -0
- package/dist/install/paths.js +83 -0
- package/dist/install/write.js +97 -0
- package/dist/live/session.js +164 -0
- package/dist/mcp/response.js +40 -0
- package/dist/server.js +59 -0
- package/dist/smoke.js +106 -0
- package/dist/tools/api.js +96 -0
- package/dist/tools/context.js +1 -0
- package/dist/tools/credentialpick.js +11 -0
- package/dist/tools/live.js +104 -0
- package/dist/tools/page.js +383 -0
- package/dist/tools/session.js +72 -0
- package/dist/transport/auth.js +61 -0
- package/dist/transport/credential.js +7 -0
- package/dist/transport/http.js +77 -0
- package/dist/transport/pages.js +51 -0
- package/dist/transport/socket.js +85 -0
- package/dist/vision/preview.js +30 -0
- package/dist/vision/shoot.js +103 -0
- package/package.json +66 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
First release.
|
|
6
|
+
|
|
7
|
+
An MCP stdio server that designs and operates a Store Builder site.
|
|
8
|
+
|
|
9
|
+
- **Full API reach in two tools.** `sb_api_find` searches a generated index of the
|
|
10
|
+
platform's 310 API operations — real parameter schemas, the credential each needs, and an
|
|
11
|
+
explicit flag when the platform's own document fails to describe a request body.
|
|
12
|
+
`sb_api_call` executes one, defaulting to a dry run.
|
|
13
|
+
- **Page building.** An 85-element catalog carrying the platform's own AI hints
|
|
14
|
+
(`useWhen` / `avoidWhen` / `contentTips`), the live-edit patch primitive with its three
|
|
15
|
+
admission rules, and a builder that takes a whole nested section in one call.
|
|
16
|
+
- **Four platform traps encoded as tested code**, each of which fails silently otherwise:
|
|
17
|
+
site overlays are excluded from every ROOT-level rule; global sections warn that edits
|
|
18
|
+
cascade; ROOT's children are held to `[header][middle][footer]`, which the platform
|
|
19
|
+
refuses every save without; and style writes go per breakpoint, because a visual quantity
|
|
20
|
+
written at base renders on the canvas and vanishes on publish.
|
|
21
|
+
- **Live editing.** `sb_live_join` joins the editor's room as a visible peer — edits appear
|
|
22
|
+
in anyone's open editor as they happen. The client always yields: it never answers a
|
|
23
|
+
snapshot request and re-pulls on any divergence.
|
|
24
|
+
- **Sight.** `sb_look` saves, renders through the platform's own renderer, and returns
|
|
25
|
+
screenshots plus the measured bounding box of every node.
|
|
26
|
+
- **One credential.** `SB_TOKEN` alone opens everything, from the store's **Apps → AI agent**
|
|
27
|
+
screen.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Store Builder
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# `sbuilder-mcp`
|
|
2
|
+
|
|
3
|
+
An MCP **stdio** server that lets an AI agent operate a [Store Builder](https://sbuilder.io.vn)
|
|
4
|
+
site end to end — design its pages, fill them with real data, look at the result, and
|
|
5
|
+
publish it — with no human clicking anything.
|
|
6
|
+
|
|
7
|
+
*[Tiếng Việt](./README.vi.md)*
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
One command writes this server into every agent client on your machine:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx -y sbuilder-mcp install --token wbk_… --api https://your-host
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
It knows Claude Code, Claude Desktop, Cursor, Windsurf, VS Code and Codex, and installs into
|
|
18
|
+
the ones it finds. Name them with `--client cursor,codex`, or rehearse with `--dry-run`.
|
|
19
|
+
|
|
20
|
+
It **merges**: the servers already in those files stay, whatever it replaces is copied to
|
|
21
|
+
`<file>.sbuilder-backup`, and a config it cannot parse is refused rather than overwritten —
|
|
22
|
+
a file with a trailing comma is far likelier than one worth discarding, and it is what you
|
|
23
|
+
need to fix it.
|
|
24
|
+
|
|
25
|
+
The store's **Apps → AI agent** screen hands you this command with the key already in it.
|
|
26
|
+
|
|
27
|
+
<details><summary>Or configure a client by hand</summary>
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"mcpServers": {
|
|
32
|
+
"sbuilder": {
|
|
33
|
+
"command": "npx",
|
|
34
|
+
"args": ["-y", "sbuilder-mcp"],
|
|
35
|
+
"env": { "SB_API": "https://api.your-host", "SB_TOKEN": "wbk_…" }
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
</details>
|
|
42
|
+
|
|
43
|
+
## Getting the key
|
|
44
|
+
|
|
45
|
+
Open your store, go to **Apps → AI agent**, and press **Create key**. That screen hands you
|
|
46
|
+
the config block for your client with the key already in it — this whole section is what it
|
|
47
|
+
saves you reading.
|
|
48
|
+
|
|
49
|
+
One key is all you need. It reaches both the partner surface (`/api/v1`) and the private
|
|
50
|
+
site API, including the page document and the live-edit socket, and it is bounded three ways
|
|
51
|
+
on every request: its own scopes, the live role of the member who created it, and the single
|
|
52
|
+
store it belongs to.
|
|
53
|
+
|
|
54
|
+
`SB_EMAIL` + `SB_PASSWORD` remain optional, and buy exactly one thing: **account-level**
|
|
55
|
+
calls — listing your sites, managing members and roles — which a key deliberately cannot
|
|
56
|
+
make, because those mean "this person's account".
|
|
57
|
+
|
|
58
|
+
`SB_API` defaults to `http://localhost:8080`. Secrets are read from the environment only.
|
|
59
|
+
|
|
60
|
+
## Tools
|
|
61
|
+
|
|
62
|
+
| Tool | What it does |
|
|
63
|
+
| --- | --- |
|
|
64
|
+
| `sb_connect` | Log in, list the sites this account can operate, report which credentials are present |
|
|
65
|
+
| `sb_site_list` | List the sites this account can operate |
|
|
66
|
+
| `sb_api_find` | Find API operations by intent — returns real parameter schemas, the credential each needs, and an explicit note when the platform's document fails to describe a request body |
|
|
67
|
+
| `sb_api_call` | Execute one operation. Defaults to a dry run that sends nothing |
|
|
68
|
+
| `sb_page_open` | Open a page for editing and return its outline |
|
|
69
|
+
| `sb_outline` | The open page as a compressed tree — never a raw document dump |
|
|
70
|
+
| `sb_node_read` | One node in full, with a warning if it is a shared global |
|
|
71
|
+
| `sb_catalog_search` | Find an element by what it should do, using the platform's own AI hints |
|
|
72
|
+
| `sb_traits_for` | Which trait groups an element accepts, plus defaults and containment rules |
|
|
73
|
+
| `sb_add` | Add an element — or a whole nested subtree — in one call |
|
|
74
|
+
| `sb_set` | Write style/config/specials. Per breakpoint by default |
|
|
75
|
+
| `sb_move` | Move a node to another parent |
|
|
76
|
+
| `sb_remove` | Remove a node and its subtree |
|
|
77
|
+
| `sb_duplicate` | Copy a node and its subtree under fresh ids, right after the original |
|
|
78
|
+
| `sb_templates` | The store's saved section templates — designed sections to start from |
|
|
79
|
+
| `sb_template_use` | Instantiate a template into a page |
|
|
80
|
+
| `sb_page_list` | Every page on the site |
|
|
81
|
+
| `sb_page_create` | Create a page |
|
|
82
|
+
| `sb_publish` | Compile the draft into the live page (cascades to shared globals) |
|
|
83
|
+
| `sb_review` | Every defect a visitor would see, each with the command that fixes it |
|
|
84
|
+
| `sb_live_join` | Join the editor's live-edit room as a visible peer — edits then appear live |
|
|
85
|
+
| `sb_look` | Save, render, and return screenshots plus measured node boxes |
|
|
86
|
+
| `sb_bind` | Bind a node's content to real store data |
|
|
87
|
+
|
|
88
|
+
Twenty-three tools, **310 API operations**. `sb_api_find` is an index rather than a tool per endpoint,
|
|
89
|
+
so the tool list stays short while everything the platform can do stays reachable — and
|
|
90
|
+
operations added to the platform arrive with the next `npm run codegen`.
|
|
91
|
+
|
|
92
|
+
Full reference: [`docs/tools.md`](./docs/tools.md).
|
|
93
|
+
|
|
94
|
+
## How it stays in sync
|
|
95
|
+
|
|
96
|
+
The platform publishes two generated, committed artifacts. A build step reads them out of a
|
|
97
|
+
checkout and emits the catalog:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
WB_REPO=/path/to/web_builder npm run codegen
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
So this repository vendors no platform code — it depends on two data files with a
|
|
104
|
+
maintained contract. `src/catalog/api.generated.ts` is committed, so `npm install` needs no
|
|
105
|
+
checkout at all.
|
|
106
|
+
|
|
107
|
+
## Development
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
npm run build # tsc -> dist/
|
|
111
|
+
npm test # vitest
|
|
112
|
+
npm run smoke # offline self-test; must print ALL GOOD
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Contributor guide: [`CLAUDE.md`](./CLAUDE.md). Design rationale:
|
|
116
|
+
[`docs/superpowers/specs/`](./docs/superpowers/specs/).
|
|
117
|
+
|
|
118
|
+
## Designing safely
|
|
119
|
+
|
|
120
|
+
Four platform rules fail **silently** if a client does not know them, so they are encoded
|
|
121
|
+
here as tested code rather than advice:
|
|
122
|
+
|
|
123
|
+
- **Band order** — ROOT's children must read `[header][middle][footer]`, or the platform
|
|
124
|
+
refuses every save.
|
|
125
|
+
- **Site overlays** (the cart drawer, pop-ups) are composed onto ROOT on read and stripped
|
|
126
|
+
on write; they are excluded from every ROOT-level rule and cannot be edited through the
|
|
127
|
+
page tools.
|
|
128
|
+
- **Global sections** are shared masters — editing one changes every page carrying it, and
|
|
129
|
+
publishing cascades. Any result touching one says so.
|
|
130
|
+
- **Responsive by default** — `sb_set` writes per breakpoint, because a design should
|
|
131
|
+
respond. Base is the cascade's fallback layer, not a trap.
|
|
132
|
+
|
|
133
|
+
## Status
|
|
134
|
+
|
|
135
|
+
All three phases shipped: authentication and full API reach; the page document, patch
|
|
136
|
+
protocol, builder and the four traps; the live-edit socket, the yield rule, and the vision
|
|
137
|
+
loop.
|
|
138
|
+
|
|
139
|
+
Requires **Node ≥22** (the global `WebSocket`) and, for `sb_look` only, **system Google
|
|
140
|
+
Chrome** — `playwright-core` bundles no browser, so installing downloads nothing.
|
|
141
|
+
|
|
142
|
+
MIT.
|
package/README.vi.md
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# `sbuilder-mcp`
|
|
2
|
+
|
|
3
|
+
Máy chủ MCP chạy trên **stdio**, cho phép một AI agent vận hành trọn vẹn một site
|
|
4
|
+
[Store Builder](https://sbuilder.io.vn) — thiết kế trang, đổ dữ liệu thật vào, tự nhìn kết
|
|
5
|
+
quả rồi xuất bản — mà không cần người bấm gì.
|
|
6
|
+
|
|
7
|
+
*[English](./README.md)*
|
|
8
|
+
|
|
9
|
+
## Cài đặt
|
|
10
|
+
|
|
11
|
+
Một lệnh ghi server này vào mọi agent client trên máy bạn:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx -y sbuilder-mcp install --token wbk_… --api https://your-host
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Nó biết Claude Code, Claude Desktop, Cursor, Windsurf, VS Code và Codex, và cài vào những
|
|
18
|
+
cái nó tìm thấy. Chỉ định bằng `--client cursor,codex`, hoặc diễn thử với `--dry-run`.
|
|
19
|
+
|
|
20
|
+
Nó **gộp**: các server đã có trong file được giữ nguyên, thứ nó thay thế được chép sang
|
|
21
|
+
`<file>.sbuilder-backup`, và một config nó không đọc được thì bị từ chối chứ không ghi đè —
|
|
22
|
+
một file thừa dấu phẩy khả dĩ hơn nhiều một file đáng vứt, và đó chính là thứ bạn cần để sửa.
|
|
23
|
+
|
|
24
|
+
Màn hình **Apps → AI agent** của cửa hàng đưa sẵn lệnh này kèm khoá.
|
|
25
|
+
|
|
26
|
+
<details><summary>Hoặc tự cấu hình từng client</summary>
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"mcpServers": {
|
|
31
|
+
"sbuilder": {
|
|
32
|
+
"command": "npx",
|
|
33
|
+
"args": ["-y", "sbuilder-mcp"],
|
|
34
|
+
"env": { "SB_API": "https://api.your-host", "SB_TOKEN": "wbk_…" }
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
</details>
|
|
41
|
+
|
|
42
|
+
## Lấy khoá ở đâu
|
|
43
|
+
|
|
44
|
+
Mở cửa hàng của bạn, vào **Apps → AI agent**, bấm **Tạo khoá**. Màn hình đó đưa luôn khối
|
|
45
|
+
cấu hình cho client bạn dùng, khoá đã điền sẵn — cả mục này chỉ để bạn khỏi phải đọc.
|
|
46
|
+
|
|
47
|
+
Một khoá là đủ. Nó với tới cả bề mặt đối tác (`/api/v1`) lẫn private site API, gồm tài liệu
|
|
48
|
+
trang và socket live-edit, và bị chặn ba lớp ở mỗi request: scope của chính nó, role sống của
|
|
49
|
+
thành viên đã tạo ra nó, và đúng một cửa hàng nó thuộc về.
|
|
50
|
+
|
|
51
|
+
`SB_EMAIL` + `SB_PASSWORD` vẫn tuỳ chọn, và mua đúng một thứ: các lệnh **cấp tài khoản** —
|
|
52
|
+
liệt kê site, quản lý thành viên và role — mà khoá cố ý không làm được, vì những thứ đó nghĩa
|
|
53
|
+
là "tài khoản của người này".
|
|
54
|
+
|
|
55
|
+
`SB_API` mặc định `http://localhost:8080`. Bí mật chỉ đọc từ biến môi trường.
|
|
56
|
+
|
|
57
|
+
## Bộ tool
|
|
58
|
+
|
|
59
|
+
| Tool | Làm gì |
|
|
60
|
+
| --- | --- |
|
|
61
|
+
| `sb_connect` | Đăng nhập, liệt kê site tài khoản vận hành được, báo đang có credential nào |
|
|
62
|
+
| `sb_site_list` | Liệt kê site tài khoản vận hành được |
|
|
63
|
+
| `sb_api_find` | Tìm operation theo ý định — trả về schema tham số thật, credential cần dùng, và cảnh báo rõ ràng khi tài liệu của nền tảng không mô tả request body |
|
|
64
|
+
| `sb_api_call` | Chạy một operation. Mặc định chạy khô, không gửi gì |
|
|
65
|
+
| `sb_page_open` | Mở một trang để sửa và trả về outline |
|
|
66
|
+
| `sb_outline` | Trang đang mở dạng cây nén — không bao giờ dump tài liệu thô |
|
|
67
|
+
| `sb_node_read` | Một node đầy đủ, kèm cảnh báo nếu nó là global dùng chung |
|
|
68
|
+
| `sb_catalog_search` | Tìm element theo việc nó cần làm, dùng chính AI hints của nền tảng |
|
|
69
|
+
| `sb_traits_for` | Element nhận nhóm trait nào, kèm default và luật chứa con |
|
|
70
|
+
| `sb_add` | Thêm một element — hoặc cả cây con lồng nhau — trong một lần gọi |
|
|
71
|
+
| `sb_set` | Ghi style/config/specials. Mặc định theo breakpoint |
|
|
72
|
+
| `sb_move` | Chuyển node sang cha khác |
|
|
73
|
+
| `sb_remove` | Xoá node và cả cây con |
|
|
74
|
+
| `sb_duplicate` | Nhân bản một node và cả cây con dưới id mới, ngay sau bản gốc |
|
|
75
|
+
| `sb_templates` | Section template đã lưu của cửa hàng — section thiết kế sẵn để bắt đầu |
|
|
76
|
+
| `sb_template_use` | Thả một template vào trang |
|
|
77
|
+
| `sb_page_list` | Mọi trang của site |
|
|
78
|
+
| `sb_page_create` | Tạo một trang |
|
|
79
|
+
| `sb_publish` | Biên dịch bản nháp thành trang live (lan sang global dùng chung) |
|
|
80
|
+
| `sb_review` | Mọi khiếm khuyết người xem sẽ thấy, kèm lệnh sửa từng cái |
|
|
81
|
+
| `sb_live_join` | Vào phòng live-edit của editor như một peer nhìn thấy được — sửa gì hiện ngay |
|
|
82
|
+
| `sb_look` | Lưu, render, trả về ảnh chụp kèm box đo được của từng node |
|
|
83
|
+
| `sb_bind` | Gắn nội dung một node vào dữ liệu cửa hàng thật |
|
|
84
|
+
|
|
85
|
+
Hai mươi ba tool, **310 operation API**. `sb_api_find` là một chỉ mục chứ không phải mỗi endpoint một
|
|
86
|
+
tool, nên danh sách tool vẫn ngắn trong khi mọi thứ nền tảng làm được vẫn với tới — và
|
|
87
|
+
operation mới thêm bên nền tảng sẽ tự có sau lần `npm run codegen` kế tiếp.
|
|
88
|
+
|
|
89
|
+
Tra cứu đầy đủ: [`docs/tools.vi.md`](./docs/tools.vi.md).
|
|
90
|
+
|
|
91
|
+
## Cách nó không bị lệch
|
|
92
|
+
|
|
93
|
+
Nền tảng có sẵn hai artifact đã sinh và đã commit. Một bước build đọc chúng từ một checkout
|
|
94
|
+
rồi sinh ra catalog:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
WB_REPO=/duong/dan/web_builder npm run codegen
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Nhờ vậy repo này không vendor dòng code nào của nền tảng — nó chỉ phụ thuộc vào hai file dữ
|
|
101
|
+
liệu có hợp đồng được bảo trì. `src/catalog/api.generated.ts` được commit, nên `npm install`
|
|
102
|
+
không cần checkout nào cả.
|
|
103
|
+
|
|
104
|
+
## Phát triển
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
npm run build # tsc -> dist/
|
|
108
|
+
npm test # vitest
|
|
109
|
+
npm run smoke # tự kiểm offline; phải in ALL GOOD
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Hướng dẫn đóng góp: [`CLAUDE.md`](./CLAUDE.md). Lý do thiết kế:
|
|
113
|
+
[`docs/superpowers/specs/`](./docs/superpowers/specs/).
|
|
114
|
+
|
|
115
|
+
## Thiết kế an toàn
|
|
116
|
+
|
|
117
|
+
Bốn luật của nền tảng hỏng **im lặng** nếu client không biết, nên chúng được viết thành code
|
|
118
|
+
có test chứ không phải lời khuyên:
|
|
119
|
+
|
|
120
|
+
- **Thứ tự băng** — con của ROOT phải đọc `[header][middle][footer]`, sai là nền tảng từ
|
|
121
|
+
chối mọi lần lưu.
|
|
122
|
+
- **Site overlay** (cart drawer, pop-up) được ghép lên ROOT lúc đọc và bóc ra lúc ghi; nó bị
|
|
123
|
+
loại khỏi mọi luật cấp ROOT và không sửa được qua bộ page tool.
|
|
124
|
+
- **Global section** là master dùng chung — sửa một cái là đổi mọi trang mang nó, và publish
|
|
125
|
+
thì lan. Mọi kết quả đụng tới nó đều nói rõ.
|
|
126
|
+
- **Mặc định responsive** — `sb_set` ghi theo breakpoint, vì một thiết kế nên đáp ứng. Base
|
|
127
|
+
là lớp dự phòng của cascade, không phải cái bẫy.
|
|
128
|
+
|
|
129
|
+
## Trạng thái
|
|
130
|
+
|
|
131
|
+
Cả ba giai đoạn đã xong: xác thực và với tới toàn bộ API; tài liệu trang, giao thức patch,
|
|
132
|
+
builder và bốn cái bẫy; socket live-edit, luật nhường, và vòng lặp thị giác.
|
|
133
|
+
|
|
134
|
+
Cần **Node ≥22** (WebSocket toàn cục) và, chỉ với `sb_look`, **Google Chrome của hệ thống** —
|
|
135
|
+
`playwright-core` không kèm trình duyệt nào nên lúc cài không tải gì.
|
|
136
|
+
|
|
137
|
+
MIT.
|