From 820804cbafc0ab283fd7097669844e6acd61928d Mon Sep 17 00:00:00 2001 From: Ho Ngoc Hai Date: Fri, 6 Feb 2026 22:13:07 +0700 Subject: [PATCH] feat: Introduce and document MCP Pencil integration with a new comprehensive reference for its tools and workflow. --- .agent/skills/pencil-design/SKILL.md | 49 ++++ .../pencil-design/references/MCP_TOOLS.md | 215 ++++++++++++++++++ 2 files changed, 264 insertions(+) create mode 100644 .agent/skills/pencil-design/references/MCP_TOOLS.md diff --git a/.agent/skills/pencil-design/SKILL.md b/.agent/skills/pencil-design/SKILL.md index f5fafd4a..d3cbdce5 100644 --- a/.agent/skills/pencil-design/SKILL.md +++ b/.agent/skills/pencil-design/SKILL.md @@ -20,6 +20,54 @@ Use this skill when: - Organizing enterprise UI Kits with Atomic Design / Tổ chức UI Kits doanh nghiệp - Working with modular design systems / Làm việc với hệ thống thiết kế module +## MCP Pencil Integration / Tích Hợp MCP Pencil + +> [!TIP] +> MCP Pencil cho phép tương tác realtime với Pencil editor. Xem chi tiết tại [MCP Tools Reference](./references/MCP_TOOLS.md). + +### Khi Nào Dùng MCP vs Build Scripts + +| Tác vụ | MCP Pencil | Build Scripts | +|--------|------------|---------------| +| Thiết kế UI realtime | ✅ `batch_design` | ❌ | +| Screenshot/verify | ✅ `get_screenshot` | ❌ | +| Style guides | ✅ `get_style_guide` | ❌ | +| Build library | ❌ | ✅ `scripts/build.py` | +| Merge files | ❌ | ✅ `scripts/build.py -m` | + +### MCP Tools Quick Reference + +``` +Document: open_document, get_editor_state, get_variables, set_variables +Design: batch_design, batch_get, snapshot_layout, find_empty_space_on_canvas +Guidelines: get_guidelines, get_style_guide_tags, get_style_guide +Verify: get_screenshot +Batch: search_all_unique_properties, replace_all_matching_properties +``` + +### MCP Workflow + +1. `get_editor_state` → Xác định file, selection, components +2. `get_guidelines("design-system")` → Hướng dẫn thiết kế +3. `get_variables` → Design tokens +4. `batch_design` → Tạo/sửa design (max 25 ops/call) +5. `get_screenshot` → Verify visual + +### batch_design Operations + +```javascript +binding=I(parent, {type: "frame", ...}) // Insert +U(nodeId, {content: "..."}) // Update +U(instance+"/child", {content: "..."}) // Update descendant +newNode=R(instance+"/slot", {...}) // Replace +copied=C(sourceId, parent, {...}) // Copy +M(nodeId, newParent, index) // Move +D(nodeId) // Delete +G(nodeId, "ai", "prompt...") // Generate image +``` + +--- + ## Core Concepts / Khái Niệm Cốt Lõi ### What is Pencil / Pencil là gì @@ -359,6 +407,7 @@ python3 scripts/build.py --library ### Detailed References +- [MCP Tools Reference](./references/MCP_TOOLS.md) - MCP Pencil integration, realtime design tools - [File Format Reference](./references/FILE_FORMAT.md) - Complete .pen structure, element types, properties - [Build System Reference](./references/BUILD_SYSTEM.md) - Build configuration, workflows, troubleshooting - [Atomic Design Reference](./references/ATOMIC_DESIGN.md) - Enterprise UI Kit organization, extraction scripts diff --git a/.agent/skills/pencil-design/references/MCP_TOOLS.md b/.agent/skills/pencil-design/references/MCP_TOOLS.md new file mode 100644 index 00000000..400b67de --- /dev/null +++ b/.agent/skills/pencil-design/references/MCP_TOOLS.md @@ -0,0 +1,215 @@ +# MCP Pencil Tools Reference / Tham Chiếu MCP Pencil + +> [!NOTE] +> MCP Pencil cho phép tương tác realtime với Pencil editor thông qua các tools. +> Yêu cầu: Có file `.pen` đang mở trong Pencil editor. + +## Khi Nào Dùng MCP vs Build Scripts + +| Tác vụ | MCP Pencil | Build Scripts | +|--------|------------|---------------| +| Thiết kế UI realtime | ✅ Dùng MCP | ❌ | +| Xem screenshot | ✅ `get_screenshot` | ❌ | +| Lấy style guide | ✅ `get_style_guide` | ❌ | +| Build library từ Atomic | ❌ | ✅ `scripts/build.py` | +| Merge nhiều files | ❌ | ✅ `scripts/build.py -m` | +| Extract components | ❌ | ✅ `scripts/extract-atomic.py` | + +--- + +## Tools Overview + +### 1. Document Management + +| Tool | Mục đích | +|------|----------| +| `open_document` | Mở file `.pen` hoặc tạo mới (`"new"`) | +| `get_editor_state` | Lấy state hiện tại: file đang mở, selection, components | +| `get_variables` | Đọc design tokens (colors, spacing, typography) | +| `set_variables` | Cập nhật design tokens | + +### 2. Design Operations + +| Tool | Mục đích | +|------|----------| +| `batch_design` | Insert/Update/Replace/Copy/Move/Delete nodes | +| `batch_get` | Đọc nodes theo ID hoặc search patterns | +| `snapshot_layout` | Kiểm tra layout structure, tìm overlapping | +| `find_empty_space_on_canvas` | Tìm vị trí trống để đặt frame mới | + +### 3. Guidelines & Inspiration + +| Tool | Mục đích | +|------|----------| +| `get_guidelines` | Lấy hướng dẫn theo topic: `design-system`, `landing-page`, `table`, `code`, `tailwind` | +| `get_style_guide_tags` | Liệt kê tags có sẵn cho style guide | +| `get_style_guide` | Lấy style guide theo tags hoặc tên | + +### 4. Verification + +| Tool | Mục đích | +|------|----------| +| `get_screenshot` | Chụp screenshot node để verify | + +### 5. Batch Operations + +| Tool | Mục đích | +|------|----------| +| `search_all_unique_properties` | Tìm all unique values của properties | +| `replace_all_matching_properties` | Thay thế properties matching | + +--- + +## batch_design Operations + +Operations trong `batch_design` dùng syntax đặc biệt: + +```javascript +// Insert (I) - Thêm node mới +binding=I(parent, {type: "frame", layout: "vertical", ...}) + +// Update (U) - Cập nhật properties (KHÔNG dùng cho children) +U(nodeId, {content: "New text", fill: "$--foreground"}) +U(instanceId+"/childId", {content: "Override text"}) + +// Replace (R) - Thay thế node hoàn toàn (dùng cho slot content) +newNode=R(instanceId+"/slotId", {type: "text", content: "Custom"}) + +// Copy (C) - Copy node (tạo ref nếu reusable) +copiedNode=C(sourceId, parent, {positionDirection: "right", positionPadding: 100}) + +// Move (M) - Di chuyển node +M(nodeId, newParent, index) + +// Delete (D) - Xóa node +D(nodeId) + +// Generate Image (G) - Tạo image fill cho frame/rectangle +G(nodeId, "ai", "modern office workspace") // AI generated +G(nodeId, "stock", "coffee shop interior") // Stock photo +``` + +### Quy Tắc Quan Trọng + +> [!IMPORTANT] +> - Mỗi I, C, R **PHẢI** có binding name +> - Dùng `instanceId+"/childId"` để override descendants +> - **KHÔNG** dùng U() cho descendants của node vừa Copy - dùng `descendants` trong Copy operation +> - Max 25 operations mỗi `batch_design` call + +--- + +## Workflow Chuẩn + +### 1. Khởi Đầu +``` +get_editor_state(include_schema: true) +→ Xác định file, selection, reusable components +``` + +### 2. Lấy Context +``` +get_guidelines("design-system") // Hoặc "landing-page" +get_variables() // Design tokens +batch_get(patterns: [{reusable: true}], readDepth: 2) // Components +``` + +### 3. Thiết Kế +``` +// Tạo placeholder frame trước +batch_design(` +screen=I(document, {type: "frame", placeholder: true, ...}) +`) + +// Thêm content +batch_design(` +sidebar=I("screenId", {type: "ref", ref: "SidebarComp"}) +content=I("screenId", {type: "frame", ...}) +... +`) + +// Xóa placeholder khi xong +batch_design(`U("screenId", {placeholder: false})`) +``` + +### 4. Verify +``` +get_screenshot(nodeId: "screenId") +→ Kiểm tra visual output +``` + +--- + +## Ví Dụ: Dashboard Screen + +```javascript +// Batch 1: Structure +screen=I(document, {type: "frame", name: "Dashboard", layout: "horizontal", width: 1440, height: 900, fill: "$--background", placeholder: true}) +sidebar=I(screen, {type: "ref", ref: "SidebarComp", height: "fill_container"}) +main=I(screen, {type: "frame", layout: "vertical", width: "fill_container", height: "fill_container", padding: 32, gap: 24}) + +// Batch 2: Sidebar items +item1=I(sidebar+"/contentSlot", {type: "ref", ref: "SidebarItem", descendants: {"labelId": {content: "Dashboard"}}}) +item2=I(sidebar+"/contentSlot", {type: "ref", ref: "SidebarItem", descendants: {"labelId": {content: "Users"}}}) + +// Batch 3: Main content +header=I("mainId", {type: "frame", layout: "horizontal", width: "fill_container", justifyContent: "space_between"}) +title=I(header, {type: "text", content: "Dashboard", fontSize: 24, fontWeight: "600", fill: "$--foreground"}) +cards=I("mainId", {type: "frame", layout: "horizontal", gap: 16}) +card1=I(cards, {type: "ref", ref: "CardComp", width: "fill_container"}) +card2=I(cards, {type: "ref", ref: "CardComp", width: "fill_container"}) + +// Batch 4: Finalize +U("screenId", {placeholder: false}) +``` + +--- + +## Common Patterns + +### Override Component Text +```javascript +button=I(container, {type: "ref", ref: "ButtonComp"}) +U(button+"/labelText", {content: "Submit"}) +``` + +### Replace Slot Content +```javascript +card=I(container, {type: "ref", ref: "CardComp"}) +customContent=R(card+"/contentSlot", {type: "frame", layout: "vertical", gap: 8, children: [ + {type: "text", content: "Custom Title", fontSize: 18}, + {type: "text", content: "Description", fontSize: 14} +]}) +``` + +### Add Image to Frame +```javascript +heroFrame=I(container, {type: "frame", width: 600, height: 400}) +G(heroFrame, "ai", "modern tech office, bright, professional") +``` + +### Find Empty Space +```javascript +find_empty_space_on_canvas(width: 1440, height: 900, padding: 100, direction: "right") +→ Trả về {x, y} cho vị trí trống +``` + +--- + +## Troubleshooting + +| Vấn đề | Giải pháp | +|--------|-----------| +| "A file needs to be open" | Dùng `open_document` trước | +| Update descendants fail | Dùng path: `instanceId+"/childId"` | +| Copy descendants fail | Dùng `descendants` trong Copy, KHÔNG Update riêng | +| Nodes overlap | Dùng `find_empty_space_on_canvas` | +| Layout broken | Kiểm tra `snapshot_layout(problemsOnly: true)` | + +--- + +## Related + +- [Design System Guidelines](./DESIGN_SYSTEM.md) - Nếu có +- [File Format Reference](./FILE_FORMAT.md) - Chi tiết .pen schema +- [Build System Reference](./BUILD_SYSTEM.md) - Scripts cho build/extract