Community图像github.com

lw-spec-mockup

用于根据规范或计划生成SVG界面示意图(屏幕、状态、对话框、控制台页面或流程),在用户询问“设计在哪里”、“画出来”或“展示所有状态”时使用,以及在提交或修改 docs/specs/assets 中的看板之前使用。使用单一库绘制生成的SVG看板。不用于规范文本(由 lw-spec-write 处理)。

lw-spec-mockup 是什么?

该技能专注于生成SVG格式的界面示意图,适用于开发者在使用AI编码助手(如Claude Code、Cursor、Codex)时,需要快速将规范或计划可视化的场景。它严格遵循一套文件命名、颜色(从令牌文件读取)、文本(从i18n目录获取真实文案)和数据(使用合理值)的规则,确保示意图的高保真度。支持桌面和手机两种表面,并内置了“现状与目标”对比、状态行展示、图钉图例以及组件清单等结构,方便审查。技能通过一个名为 boards.py 的 Python 库实现,每个规范对应一个独立的 Python 脚本,运行后生成SVG文件。生成的SVG必须通过渲染为PNG图片进行视觉审查,以防止文本溢出、图钉遮挡、颜色错误等问题。该技能还强调了在看板修改后,必须重新运行脚本而非手动编辑SVG文件。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/launchwrighthq/agent-harness/tree/HEAD/skills/lw-spec-mockup

Installed? Explore more 图像 skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

规范示意图

本技能说明如何绘制。lw-spec-write 说明规范的存放位置以及页面如何渲染。

产品事实

适配器文件夹来自配置。首先读取它:

ah config get harness.adapterDir

然后读取 <adapterDir>/spec-mockup/。项目拥有它。它命名了:

事实示例
每个应用的令牌文件(按顺序)apps/console/src/styles/tokens.css
亮色和暗色值的选择器:root, .dark
lucide 图标文件夹node_modules/lucide-react/dist/esm/icons
每个带有侧边栏的应用的导航,以及它的来源控制台的路由表
真实文案的来源应用的 i18n 目录

当适配器缺失时,在绘制前向用户索要令牌文件。绝不要凭空发明一种 颜色。

格式

生成的 SVG,使用单一库绘制:此文件旁的 boards.py。每个规范都有 一个脚本 docs/specs/assets/<date>-<topic>-boards.py。它导入该库并写入 docs/specs/assets/<date>-<topic>/。绝不要手动编辑生成的 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("Dashboard: the empty state")
f = b.sidebar_app(
    GUTTER,
    160,
    t["bg"],
    t["sidebar"],
    t["ink"],
    t["muted"],
    t["active"],
    ["Dashboard"],
    "Dashboard",
    "Console",
)
b.pin(f.x + f.left + 24, f.top + 30, 1)
b.legend(
    GUTTER, 1100, [(1, "The empty state", "No widget until the product names one.", "R1")], 1440
)
b.save("docs/specs/assets/<date>-<topic>/desktop-empty.svg")
调用绘制内容
tokens(files, theme, base=, dark=, overlay=)令牌文件的已解析 --* 值。t["accent"]。缺失的令牌会引发错误。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 截图

保真度

  • 颜色来自令牌,通过 tokens()。规范脚本中的十六进制值是错误的,除非是 令牌文件中不包含的艺术作品颜色。
  • 文案是真实的。 使用应用目录中的字符串(如果存在)。新字符串要简短: 标签、值、空状态、错误或单行提示。
  • 数据是现实的。 使用合理的值,并在可能出现长数据的地方使用一个长值。

画布

表面框架
手机390 x 844,48 px 间距
桌面1440 x 900
看板宽度与框架相同,高度根据行数需要

规范绘制的内容

  1. 现状,然后是目标。 “现状”是已发布屏幕的真实截图 (today-*.png)。 “目标”是 SVG。在 Markdown 表格中并排放置它们。
  2. 每个适用的状态占一行: 默认、空、加载、错误、长文本、最小 和最大内容。
  3. 图钉和图例。 在每个发生变化的元素上放置一个带编号的图钉。在框架下,放置一个 带编号的图例:一个粗体标题,最多两行,以及它服务的规范 ID。
  4. 规范中的组件列表 在看板旁边:每个元素、它复用的组件、 以及每个新组件及其原因。

命名

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。

构建之后

构建必须匹配已批准的看板。截取构建后的屏幕并将其放在看板旁边。 差异是构建的缺陷,而不是重新绘制看板的理由。

相关技能