規格示意圖
此技能說明如何繪圖。lw-spec-write 則說明規格檔案的位置以及頁面如何渲染。
產品事實
適配器資料夾來自設定。請先讀取它:
ah config get harness.adapterDir
然後讀取 <adapterDir>/spec-mockup/。該資料夾由專案擁有。其內容如下:
| 事實 | 範例 |
|---|---|
| 每個應用程式的 token 檔案(依序排列) | apps/console/src/styles/tokens.css |
| 淺色與深色值的選擇器 | :root, .dark |
| Lucide 圖示資料夾 | node_modules/lucide-react/dist/esm/icons |
| 每個具有側邊欄的應用程式的導航及其來源 | 控制台的路由表 |
| 實際文字的來源 | 應用程式的 i18n 目錄 |
當適配器遺失時,請在使用者繪圖前詢問 token 檔案。切勿憑空發明顏色。
格式
生成的 SVG 使用一個函式庫繪製:boards.py(與此檔案位於同一目錄下)。每個規格都有一個腳本:docs/specs/assets/<日期>-<主題>-boards.py。它會匯入該函式庫並將檔案寫入 docs/specs/assets/<日期>-<主題>/。切勿手動編輯生成的 SVG:請修改腳本並重新執行。當函式庫缺少某個功能時,請將其新增到專案中位於腳本旁的輔助模組,以便下一個規格也能使用。
example.py 是一個完整的看板範例:包含桌面版和手機版的頁面,以及圖釘和圖例。執行它以查看形狀:
python3 .claude/skills/lw-spec-mockup/example.py <scratchpad>/mock --render
規格腳本的開頭如下:
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[3]
sys.path.insert(0, str(ROOT / ".claude/skills/lw-spec-mockup"))
from boards import GUTTER, Board, render, tokens
t = tokens("apps/console/src/styles/tokens.css", "light")
b = Board(1440 + 2 * GUTTER, 1200, icons="node_modules/lucide-react/dist/esm/icons")
b.title("儀表板:空狀態")
f = b.sidebar_app(
GUTTER,
160,
t["bg"],
t["sidebar"],
t["ink"],
t["muted"],
t["active"],
["儀表板"],
"儀表板",
"控制台",
)
b.pin(f.x + f.left + 24, f.top + 30, 1)
b.legend(
GUTTER, 1100, [(1, "空狀態", "在產品指定小工具之前,沒有任何小工具。", "R1")], 1440
)
b.save("docs/specs/assets/<日期>-<主題>/desktop-empty.svg")
| 呼叫 | 繪製內容 |
|---|---|
tokens(files, theme, base=, dark=, overlay=) | token 檔案中已解析的 --* 值。t["accent"]。遺失的 token 會引發錯誤。overlay 是提議的重新樣式 |
phone(x, y, bg, ink, surface, url), desktop(x, y, bg, url) | 手機(web 或 app)、瀏覽器視窗 |
sidebar_app(x, y, ...) | 具有左側邊欄的應用程式,例如控制台。從應用程式的路由表複製 nav |
screenshot(path, x, y), crop(path, ...) | 已出貨畫面的真實截圖,或其中的區域,用於「今日」欄 |
icon(name, x, y, size, color) | 看板的 icons 資料夾中的 lucide 字形 |
image(path, ...), embed_font(family, path) | 來自儲存庫的真實素材和品牌字型 |
pin, legend, caption, column_head, row_label, title | 備註。超過兩行的圖例備註會引發錯誤 |
render(svg, png, w, h) | 用於下方檢查的無頭 Chrome 截圖 |
保真度
- 顏色是 token,透過
tokens()取得。規格腳本中的十六進位值是不正確的,除非該美術素材不在 token 檔案中。 - 文字是真實的。 使用應用程式的目錄中的字串(如果存在)。新字串應簡短:一個標籤、一個值、一個空狀態、一個錯誤或一行提示。
- 數據是合理的。 使用合理的值,並且在可能出現長值的地方使用長值。
畫布
| 表面 | 框架 |
|---|---|
| 手機 | 390 x 844,48 px 間距 |
| 桌面 | 1440 x 900 |
| 看板 | 寬度與其框架相同,高度取決於其行數所需 |
規格應繪製的內容
- 首先是今日,然後是目標。 「今日」是已出貨畫面的真實截圖(
today-*.png)。「目標」是 SVG。將它們並排放置在 Markdown 表格中。 - 每個相關狀態一行:預設、空、載入、錯誤、長文字、最小和最大的內容。
- 圖釘與圖例。 在每個變更的元素上放置編號的圖釘。在框架下方放置編號的圖例:一個粗體標題、最多兩行文字,以及它所服務的規格 ID。
- 規格中緊鄰看板的元件清單:每個元素、它重複使用的元件,以及每個新元件及其原因。
命名規則
docs/specs/assets/<YYYY-MM-DD>-<topic>-boards.py
docs/specs/assets/<YYYY-MM-DD>-<topic>/<surface>-<state>.svg
docs/specs/assets/<YYYY-MM-DD>-<topic>/today-<surface>-<state>.png
規格會命名其在 assets/ 中持有的所有檔案的基礎名稱。
提交前檢查每個看板
看板的缺陷在原始碼中看不見,但在圖片中很明顯。請渲染每個看板,並使用「讀取」工具讀取 PNG。將 PNG 寫入暫存區,而非 docs/。
- 沒有文字超出其框架,且沒有圖釘遮蓋數值。
- 繪製的 UI 中的每個字串都是一個標籤、一個值、一個空狀態、一個錯誤或一個提示。
- 沒有佔位素材,也沒有用肉眼挑選的顏色。
- 規格涉及的每個狀態和表面都有其框架。
- 今日與目標並排顯示。
render 需要在 PATH 上有 google-chrome 或 chromium。
建置後
建置結果必須與已核准的看板相符。擷取建置後的畫面,並將其放在看板旁邊。差異表示建置有缺陷,而非重新繪製看板的理由。