smyw
GitHub生成单文件HTML变更预览原型,通过线框图展示界面改动、交互流程及前后端对比,支持用户直接编辑反馈并结构化返回,辅助代码实现前的方案确认与实现后的回顾。
Trigger Scenarios
Install
npx skills add nishuzumi/show-me-you-want-skill --skill smyw -g -y
SKILL.md
Frontmatter
{
"name": "smyw",
"whenToUse": "用户提出新功能、改版或重构,且会新增\/删除\/修改页面、改变交互流程、或改动前后端接口时;用户说「出个原型」「先给我看看要改什么」「画个前后对比」「展示这次的变化」时;实现完成后需要向用户展示改了什么时。",
"description": "smyw(show me you want)。在做会改动页面、交互流程或前后端接口的功能时,生成一个单文件 HTML「变更预览」:按真实界面画出每一整屏的线框(模块名和代码组件对得上),放在可拖动缩放的画布上,最外层改动的模块按编号画框(黄=修改,绿=新增,红=删除);点编号查看这一处的改动前后、相关交互步骤和函数\/接口。另有流程泳道和后端模块的前后对比。用户可以直接在 HTML 里拖动组件、把内联卡片改成按钮触发的弹窗\/下拉菜单、改文字和组件类型、写批注和整体风格意见,然后复制结构化反馈粘贴回对话。纯前端单文件,不需要服务端。默认用于写代码之前的原型阶段,也可用于实现后回顾。"
}
smyw(show me you want):变更预览 + 原型反馈
一次功能变化 → 一份 JSON spec → 一个可交互的 HTML。用户在 HTML 上看懂"改哪里、加什么、怎么触发",直接动手改方案或写批注,再把反馈交回给你。
本 skill 目录(下文称 $SKILL)里有:
scripts/build.mjs:校验 spec,生成单文件preview.html(纯前端、无外部依赖、离线可开)scripts/apply-feedback.mjs:从用户粘贴回来的反馈里取出修改后的方案,生成下一版 specreferences/spec-format.md:spec 完整字段说明,第一次写 spec 前先读一遍examples/task-tags/spec.json:完整示例(新增页、删除页、内联卡片、表格列变化、流程、后端)
构建只需要 Node ≥ 18;生成的 HTML 是纯前端的,不需要也不要启动任何服务。不要手写 HTML:永远写 spec 再 build。
什么时候用
- 默认:功能会动到页面、交互或接口时,在写代码之前先出原型(
stage: "prototype"),给用户看,等反馈或确认后再实现。 - 很小的改动(改一处文案、加一个字段)先问用户要不要预览;用户说"直接做"就跳过。
- 实现之后:把同一份 spec 改成
stage: "done",按实际实现修正,并在 note 里标出和原型的偏差,重新 build 给用户回顾。
工作流
1. 摸清现状:按真实界面画,不按功能点画
读路由、布局、页面组件、接口、模型代码,先弄清用户实际看到的一整屏长什么样:
- 一个 page = 用户看到的一整屏,而不是一个组件或一个功能点。比如「左侧侧栏 + 右侧主面板」是同一屏,要画在同一个 page 里(
root.layout: "row",侧栏w: "1/4"),不要拆成「侧栏」「详情」两个 page。不同路由或不同模式下的界面才算不同的 page。 - 模块要和代码对得上:每个区域(侧栏、头部、主面板、列表、对话框……)用它在界面上的名字做
label,用component写代码里的组件或文件(如"<TicketQueue> TicketQueue.vue")。 - 没改的模块也要画出来,写 label 和 component,不展开 children 就行(预览里会显示「内容不变,未展开」)。不要用「xxx(不变)」这种 placeholder 代替真实模块,build 会警告。
- 顺序、左右、上下要和真实界面一致,这样用户一眼能认出是哪里。
2. 写 spec
在目标项目根目录下:
.smyw/<YYYYMMDD>-<短名>/spec.json
(产物都在这个目录:preview.html、每轮的 feedback-v<N>.md、旧版 spec-v<N>.json。第一次创建 .smyw/ 时问用户是否加进 .gitignore。)
省 token 的写法:
- 第一版写完整 spec,用 JSON、缩进 2(不要用 YAML:缩进和引号容易出错,
on这类键在一些解析器里会变成布尔值)。 - 之后每一版用编辑工具只改变动的地方(改字段、插入/删除节点),不要整份重写,也不要为了改几处把整份 spec 重新读一遍。
- 用户的结构修改以补丁形式回来(见第 6、7 步),由脚本应用,不需要你读全量方案。
要点(完整说明见 references/spec-format.md,先看 examples/helpdesk-ai/spec.json):
- 一棵合并树:同一棵树同时描述前后两侧。每个节点用
change标注added / removed / modified,不写就是不变。 - 在最外层标注:整块模块是新增或删除时,只在这个模块上写
change,里面的子元素不要再逐个标。预览只给最外层改动的模块画框编号(黄 = 修改,绿 = 新增,红 = 删除),用户点编号再看这一处的改动前后。 - 修改:
change: "modified",旧值写在before里(如"before": {"label": "添加"}),旧值不存在就写null。容器改了名、里面又加了几块时,容器标 modified,新加的子块各自标 added。 - 移动:旧位置放一个
change: "removed", movedTo: "<新id>"的节点,新位置放change: "added", movedFrom: "<旧id>"的节点。 - 弹窗、抽屉、下拉菜单(二级菜单)、气泡:放在
page.overlays,trigger指向打开它的按钮 id;几个按钮打开同一个弹层时写成 id 数组。画布上会从每个触发按钮画一条弯曲连线到弹层,所以 trigger 一定要写全。 - 交互要写成数据,不要写成说明文字。「点了才出现」「点不开」「可折叠」「点击切换」这类话,改用下面三个字段(build 会对这类文字报警):
on:点击后发生什么,如[{ "action": "open", "target": "settings" }]。action 取 open(打开弹层)/ close(关闭所在弹层)/ navigate(跳到另一个 page)/ toggle(展开收起)/ show / hide / state(切换状态)/ back。hidden: true:默认不显示、点了才出现的内容(展开的详情、二级列表、节点详情……)。有元素用 toggle / show 指向它时,画布上会把它画成旁边的单独面板并连线,原位置留一个「在这里展开」的槽位。states+state:同一个元素的几种样子,如{ "done": { "label": "已验收" } },用{ "action": "state", "target": "ac-btn", "state": "done" }切换。- 下拉菜单、二级菜单、弹窗、抽屉用 overlays + trigger(也可以在按钮上写
onopen);菜单里还有一级的,用 hidden + toggle。 用户可以点右上角「▶ 演示」像 Figma 原型一样点着试,所以每个可点的东西都写上交互。
- 函数占位:用
fn写组件背后的行为,例如onClick → openTagEditor()、GET /api/tags。 note用一句话写「为什么这么改」,会出现在改动清单和详情里。id要稳定、有语义(kebab-case),并在整个 spec 内唯一,因为反馈会用 id 引用元素。questions:需要用户拍板的点写在这里(可带options),不要藏在 summary 里。flows:按用户实际操作顺序写步骤,actor取 user / frontend / backend / db / external / system,fn写函数或接口,node写这一步发生在哪个界面元素上(id,可以是数组)。详情面板靠它显示「相关交互」,流程页也能一键定位回界面。backend:模块 → 条目(api / function / model / field / table / job / event / config)。- 不要写样式。线框不表达颜色、间距、字体。用户若在意风格,会在反馈里说。
3. 构建
node $SKILL/scripts/build.mjs .smyw/<dir>/spec.json
出现 ✖ 必须修好;出现 ⚠ 要逐条看(例如 modified 却没有 before/note,用户就看不出改了什么)。
4. 交给用户
预览打开后是一张可拖动、可缩放的画布(弹层和点击后出现的内容画成旁边的单独面板,用连线连到触发它的按钮;右上角「▶ 演示」可以一屏一屏点着试):每一屏是一个完整的线框,改动处按编号画框;左侧是改动清单,点编号或清单条目会在右侧打开这一处的改动前后、修改了哪些字段、相关交互步骤和函数。
preview.html 是一个纯前端单文件,用户在哪里都能直接打开:
- 当前 harness 支持文件卡片或预览(例如 DSH 的
present)时,把preview.html作为交付物展示。DSH 侧边栏只有在设置里打开「显示代码工作视图」后才会运行页面脚本;没打开时页面会停在加载提示上,提示里已经写明怎么办。 - 否则给出文件的绝对路径,让用户用浏览器打开。如果用户和 Agent 不在同一台机器上,提醒用户把文件下载下来再打开。
在沙箱预览里,页面可能无法保存进度(页面顶部会提示),也可能无法自动复制(这时会自动选中全部反馈,让用户按 Ctrl+C)。功能本身都能正常使用。
给用户的话保持简短:3~5 条变化要点,加一句"可以直接在页面上拖动或批注,改完到「反馈」页点「复制反馈」,粘贴给我"。如果有 questions,提醒用户在「反馈」页回答(画布左侧也有入口)。
5. 原型阶段:停下来等
在用户反馈或明确确认之前,不要开始实现。
6. 读取反馈
用户会把「复制反馈」得到的 Markdown 粘贴进对话。先原样保存下来:
.smyw/<dir>/feedback-v<当前 version>.md
Markdown 里包括:
- 「整体意见」:风格标签、文字、风格参考。
- 「对 Agent 问题的回答」。
- 「批注」:每条带级别(必须改 / 建议 / 疑问)、分类(位置/布局、交互方式、组件类型、样式/风格、文案、功能缺失、功能多余、数据/字段、流程/逻辑、接口/后端)和位置,位置末尾的
#id就是 spec 里的元素 id。 - 「用户直接对方案做的修改」:按顺序记录的每一步操作(例如"把卡片「新建/编辑任务」改成弹窗,原位置放按钮…"),用来理解用户的意图。
- 「✅ 用户已确认方案」:用户点了确认。
- 末尾的
smyw-patchJSON 代码块(用户改过结构时才有):相对你给出的那一版、只包含改动的补丁,按 id 定位节点(del / move / add / set / order / top),已经相对"改动前"重新标注了增删改和移动。你不需要逐条读它,交给脚本应用即可。 - 少数情况下用户会额外勾选附带
revisedSpec(完整方案),脚本也能处理。
7. 处理反馈
- 用户改过结构(有「用户直接对方案做的修改」)时,用脚本把补丁应用为新一版 spec:
脚本会把旧 spec 备份为node $SKILL/scripts/apply-feedback.mjs .smyw/<dir>/feedback-v<N>.md .smyw/<dir>/spec.jsonspec-v<N>.json,写入 version + 1 的新 spec。出错时按提示处理,不要凭操作描述手工重放:- 「这份反馈是在 vX 上改的」:用户在旧版页面上改的,请用户刷新到最新预览重新改、重新复制。
- 「找不到 id」或补丁不完整:请用户在「反馈」页勾选「另外附带完整方案 JSON」后重新复制。
- 要先看补丁会改成什么样,加
--dry-run。
- 在新 spec 上落实批注、回答和整体意见,然后重新 build,告诉用户刷新页面(或重新打开文件)。新版本的页面从干净状态开始,旧版本里的标注不会带过来。
- 「必须改」全部落实;「建议」尽量采纳,不采纳就说明理由;「疑问」先回答。
- 样式/风格类意见在线框里体现不出来:写进
changes(area: frontend)或相关节点的 note,实现时按项目现有的设计规范和组件库落实,必要时去找用户给的参考。 - 用户的结构修改意图不清楚时(例如加了一个空按钮、把组件拖进弹窗但没说触发方式),问一句,不要猜。
- 回复用户时列出:采纳了什么、没采纳什么及原因、还要确认什么。
- 用户已确认方案,并且没有未处理的「必须改」,就开始实现。
8. 实现后(可选)
实现完成后,用户要求或变化较大时:spec 改成 stage: "done",按实际代码修正(包括实现中新增的接口、改名的函数),偏差写进 note,重新 build 给用户回顾。
常见错误
- 把一整屏拆成好几个 page(「侧栏」「详情」各一个):用户看到的同一屏要画在同一个 page 里。
- 用「xxx(不变)」placeholder 代替没改的模块:要画成真实模块(label + component),只是不展开 children。
- 整块新增的模块里每个子元素都标 added:只在最外层标。
- 把没改的模块内部细节全部展开:没改的就不展开 children。
- 把"改动后"单独再写一棵树:只用一棵合并树加 change 标注。
- 移动元素时直接改位置:会让左侧"改动前"也跟着变。请按"移动"规则写 removed + added 两个节点。
- modified 却不写 before:用户看不出改了什么。
- 把线框当视觉稿去还原 CSS:线框只是结构指南。
Version History
- 1f6d786 Current 2026-11-13 18:19


