关于 miro-code-spec
miro-code-spec 用于从 Miro 看板或单个项目提取规格内容,并保存到 `.miro/specs/`。它按类型整理文档、图表、原型、表格、画框和图片,供规划与实现时参考。
主要功能
- 01提取整板或单项规格
- 02按内容类型整理文件
- 03保存原型 HTML 与图片
- 04维护元数据索引
- 05核验文件与资源完整性
适用场景
- 01为实现工作准备 Miro 规格
- 02提取链接指向的单个项目
- 03收集看板中的全部规格项目
- 04检查提取结果和图片完整性
MCP 相关
该技能需要 Miro MCP 来发现看板项目,并获取其内容、表格和图片。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ miroapp/ miro-ai --skill miro-code-spec安装后在 Claude Code 中输入/miro-code-spec确认已加载。
附带文件references/spec-storage.md
详细介绍
提取 Miro 规格
从 Miro 看板或条目中提取规格内容,并保存到 .miro/specs/,以便在规划和实现期间引用,无需重复调用 API。
用户提供一个 URL:看板 URL(提取所有规格条目),或带有 moveToWidget / focusWidget 参数的条目 URL(提取该单个条目)。必须能够使用 Miro MCP。
工作流
1. 从用户请求中识别 URL
- 如果用户提供了 Miro URL,则使用该 URL。
- 如果没有,则向用户索要一个 URL。
2. 确定 URL 的范围
判断用户提供的是看板 URL(提取看板上的每个规格条目),还是单个条目 URL,即带有指定某个条目的 moveToWidget 或 focusWidget 查询参数的看板 URL。将 URL 原样传递给 Miro MCP——由 MCP 处理该 URL。
3. 检查/准备输出目录
- 检查
.miro/specs/是否存在且包含内容。 - 如果其中包含内容,询问用户:
- “
.miro/specs/目录中已包含文件。要如何处理?” - 选项:
- “清理并重新提取”——移除现有内容
- “添加到现有内容”——保留现有文件
- “取消”——中止操作
- “
- 如有需要,创建目录结构:
.miro/specs/ ├── documents/ # Markdown documents ├── diagrams/ # Diagram descriptions ├── prototypes/ # Containers (Markdown) and screens (HTML) ├── tables/ # Table JSON data ├── frames/ # Frame summaries ├── other/ # Unknown types (slides, etc.) └── images/ # Extracted images
4. 发现要提取的条目
对于看板 URL:
- 使用 Miro MCP 的看板概览工具,并提供看板 URL。
- 每个返回的条目都包含其类型、URL(带有
moveToWidget参数)和标题。 - 收集所有条目的类型、URL 和标题,以便提取。
对于条目 URL:
- 创建仅包含该条目的 URL 列表。
5. 创建提取任务(必须执行)
🚨 此步骤为必做项——不得跳过
为发现的每个条目创建一个内部检查清单任务,确保没有遗漏。
任务结构:
- 主题:“提取 [类型]:[标题]”(如果看板概览工具提供了标题,则使用标题;否则使用 ID)
- **描述:**包含条目类型、ID、URL 和目标文件路径
- activeForm:“正在提取 [类型]:[标题]”(如果有标题则使用标题,否则使用 ID)
包含标题的示例:
Subject: "Extract document: Product Requirements"
Description: "Extract document item 3458764612345 from board. Save to .miro/specs/documents/3458764612345.md"
activeForm: "Extracting document: Product Requirements"
不含标题的示例:
Subject: "Extract diagram: 3458764612347"
Description: "Extract diagram item 3458764612347 from board. Save to .miro/specs/diagrams/3458764612347.md"
activeForm: "Extracting diagram: 3458764612347"
⚠️ 重要:按类型创建任务的数量
严格按照以下数量创建任务:
- 每个文档 → 1 个任务
- 每个图表 → 1 个任务
- 每个原型容器 → 1 个任务
- 每个原型屏幕 → 3 个任务(HTML + 图片 + URL)
- “获取并保存 HTML:[标题]”
- “提取图片:[标题]”
- “更新图片 URL:[标题]”
- 每个画框 → 1 个任务
- 每个表格 → 1 个任务
- 每个其他条目 → 1 个任务
- 最后一步 → 1 个任务“完成元数据索引”
**关键:**原型屏幕不是 1 个任务,而是 3 个任务。如果每个屏幕只创建 1 个任务,图片就会遗漏。
命名约定:
- 使用看板概览工具提供的标题,以便于阅读
- 在文件路径中使用条目 ID,以确保唯一性并兼容文件系统
创建这些任务可确保: ✓ 跟踪所有条目 ✓ 不会遗漏任何内容 ✓ 进度清晰可见 ✓ 提取工作流井然有序
6. 初始化元数据索引
使用初始结构创建 .miro/specs/index.json:
{
"board_url": "original board URL",
"extracted_at": "ISO timestamp",
"items": [],
"images": [],
"summary": {
"total_items": 0,
"by_type": {},
"total_images": 0
}
}
每提取一个条目后,都会逐步更新此文件。
7. 提取每个项目的内容
重要:必须立即将从 MCP 工具接收的所有内容写入文件系统。不要跳过写入文件这一步。
每个项目的工作流(包含任务跟踪和渐进式索引更新):
对于大多数项目(文档、图表、容器、画框、表格和其他项目):
- 更新内部检查清单,将该项目标记为
in_progress - 调用相应的 MCP 工具获取内容
- 立即将内容写入磁盘
- 读取当前的
index.json,将该项目添加到 items 数组,然后写入更新后的index.json - 更新内部检查清单,将该项目标记为
completed
对于原型屏幕(强制使用子 Agent 工作流):
- 为每个屏幕启动一个子 Agent,以避免上下文膨胀
- 子 Agent 执行全部 3 个步骤:获取 HTML → 提取图片 → 更新 URL
- 大型 HTML 内容保留在子 Agent 的上下文中,绝不进入主上下文
文档项目:
- 使用项目 URL 调用相应的 Miro MCP 项目检索工具
- 必须将内容写入
.miro/specs/documents/<board item ID>.md - 如果内容中有标题,则提取标题
- 使用此项目更新
index.json
图表项目:
- 使用项目 URL 调用相应的 Miro MCP 项目检索工具
- 必须将内容写入
.miro/specs/diagrams/<board item ID>.md - 使用此项目更新
index.json
原型容器项目:
- 使用项目 URL 调用相应的 Miro MCP 项目检索工具
- 必须将内容写入
.miro/specs/prototypes/<board item ID>-container.md - 使用此项目更新
index.json
原型屏幕项目(必须通过子 Agent 执行 3 项任务的工作流):
⚠️ 每个原型屏幕都必须使用子 Agent 执行 3 项独立任务
使用子 Agent 的原因: Miro MCP 上下文工具会为原型屏幕返回大量 HTML,导致主 Agent 的上下文膨胀。子 Agent 可将这些内容限制在自身上下文中,大型 HTML 不会进入主对话。
对于每个原型屏幕,启动单个子 Agent(使用 subagent_type: "general-purpose"),依次执行全部 3 个步骤。向子 Agent 提供所有必要的上下文:
子 Agent 提示词模板:
Extract prototype screen and its images from Miro board.
Context:
- Miro board URL targeting the prototype screen: [url]
Execute these 3 tasks in order:
Task 1: Get and save HTML
- Call the appropriate Miro MCP item-retrieval tool with the item URL
- Save the returned raw HTML to .miro/specs/prototypes/<board item ID>-screen.html
- Read index.json, add this item to items array, Write updated index.json
Task 2: Extract images
- Read the saved HTML file
- Parse HTML for ALL image URLs in `src` attributes
- For EACH image URL found:
1. Extract resource ID from URL path
2. Call the appropriate Miro MCP image tool to obtain a download URL for the image
3. Take the download URL from response
4. Download: `curl -sL -o .miro/specs/images/<image resource ID>.png "[download_url]"`
5. Read index.json, add image entry to images array, Write updated index.json:
{"id": "<image resource ID>", "path": "images/<image resource ID>.png", "referenced_by": ["prototypes/<board item ID>-screen.html"]}
- If any download fails: log warning, continue with others
Task 3: Update image URLs in HTML
- Read the HTML file from .miro/specs/prototypes/<board item ID>-screen.html
- Replace ALL original image URLs with relative paths: src="../images/<image resource ID>.png"
- Save the updated HTML
- Verify all image src attributes now point to ../images/
Report back: number of images found, downloaded, and any failures.
主 Agent 对每个屏幕的工作流:
- 更新内部检查清单,将“获取并保存 HTML:[title]”标记为
in_progress - 使用上述提示词启动子 Agent
- 子 Agent 完成后,将该屏幕的全部 3 项任务标记为
completed - 继续处理下一个屏幕
⚠️ 原型屏幕的关键要求:
- ✗ 不要由主 Agent 调用屏幕的 Miro MCP 上下文工具(避免上下文膨胀)
- ✓ 每个原型屏幕始终使用子 Agent
- ✓ 为每个原型屏幕创建 3 项任务(便于查看进度)
- ✓ 子 Agent 完成全部 3 项任务:HTML → 图片 → URL
- ✓ 使用 Miro MCP 图片工具获取下载 URL,然后使用 curl 下载
- ✓ 继续处理下一个屏幕前,必须将所有图片 URL 替换为本地路径
画框项目:
- 使用项目 URL 调用相应的 Miro MCP 项目检索工具
- 必须将内容写入
.miro/specs/frames/<board item ID>.md - 使用此项目更新
index.json
表格项目:
- 对表格项目调用相应的 Miro MCP 表格检索工具
- 必须将 JSON 内容写入
.miro/specs/tables/<board item ID>.json - 在 JSON 中包含列定义和所有行数据
- 使用此项目更新
index.json
未知/其他项目类型(例如幻灯片或任何新类型):
- 使用项目 URL 调用相应的 Miro MCP 项目检索工具
- 必须将内容写入
.miro/specs/other/<board item ID>.md - 在元数据中保留原始类型名称以供参考
- 使用此项目更新
index.json
8. 完成元数据索引
读取当前的 index.json 并计算 summary 部分:
- 根据 items 数组统计
total_items - 按 type 字段对项目分组,统计
by_type - 根据 images 数组统计
total_images
使用计算出的 summary 更新 index.json:
{
"summary": {
"total_items": 8,
"by_type": {
"document": 2,
"diagram": 2,
"prototype": 2,
"table": 1,
"frame": 1
},
"total_images": 3
}
}
必须写入更新后的 index.json。
9. 验证并显示摘要
验证清单(必须执行):
- 统计实际写入
.miro/specs/目录的文件数 - 验证文件数与已处理的项目数一致
- 如果不一致,找出并保存所有缺失的项目
- 原型屏幕:验证所有图片 URL 均已替换为本地路径
- 检查所有任务是否都已标记为已完成
- 检查
.miro/specs/images/中的图片数是否与index.json的total_images一致
向用户显示:
- 提取的项目总数(按类型分类)
- 写入磁盘的文件总数
- 下载并嵌入的图片总数
- 输出目录路径
- 后续步骤:“使用这些规格进行规划和实现”
如果验证失败,请勿报告成功:
- 如果任何原型屏幕的 HTML 中仍保留原始图片 URL → 图片将无法在本地正常显示
- 如果任务数与项目数不一致 → 有些项目被跳过了
- 完成前重新提取缺失的项目
应避免的常见错误
🚨 以下是导致提取失败或不完整的最常见原因:
-
未创建任务
- ✗ 错误:提取所有项目,但不创建任务
- ✓ 正确:提取前,为每个项目创建一项内部清单任务
- 结果:项目会被跳过,进度也无法追踪
-
将原型屏幕视为一个任务
- ✗ 错误:为一个原型屏幕创建 1 个任务
- ✓ 正确:创建 3 个任务(HTML、图片、URL),并使用子 Agent
- 结果:图片永远不会被提取
-
由主 Agent 调用屏幕的 MCP 上下文工具
- ✗ 错误:直接从主 Agent 调用 Miro MCP 上下文工具处理原型屏幕(大量 HTML 会撑大上下文)
- ✓ 正确:为每个屏幕启动一个子 Agent — HTML 留在子 Agent 的上下文中
- 结果:主 Agent 的上下文溢出,提取失败
-
未解析 HTML 中的图片
- ✗ 错误:跳过 HTML 解析,假设其中不存在图片
- ✓ 正确:搜索 HTML 中所有图片的
src属性 - 结果:图片无法被发现或下载
-
未更新 HTML 中的图片 URL
- ✗ 错误:下载图片,却在 HTML 中保留原始 URL
- ✓ 正确:将所有原始 URL 替换为
../images/[id].png - 结果:HTML 仍引用远程 URL,而非本地文件
-
未追踪图片元数据
- ✗ 错误:下载图片,却不更新
index.json - ✓ 正确:将图片条目添加到
index.json的 images 数组中 - 结果:无法追踪每张图片属于哪个屏幕
- ✗ 错误:下载图片,却不更新
-
未验证是否完成
- ✗ 错误:未检查文件便结束提取
- ✓ 正确:验证所有任务均已完成、所有图片均已下载、所有 URL 均已替换
- 结果:太晚才发现提取不完整
错误处理
- 如果 Miro MCP 不可用 → 告知用户需要安装它
- 如果 URL 无效 → 请用户提供有效的 Miro URL
- 如果未找到看板或项目 → 显示错误,并请用户提供有效的 URL
- 如果某个项目的上下文获取失败 → 记录警告,并继续处理其他项目
- 如果图片下载失败 → 记录警告,但仍使用相对路径更新 HTML(以便查看失败情况)
实现说明
文件写入:
- 重要: 必须将从 MCP 获取的每一项内容写入磁盘
- 流程:调用 MCP → 获取内容 → 写入文件 → 确认已保存
- 切勿跳过文件写入步骤——仅保存在内存中的内容会丢失
- 写入所有文件类型:.md、.html、.json、.png
目录操作:
- 使用 Bash 进行目录操作(mkdir、清理时使用 rm)
- 写入文件前先创建目录
输出:
- 控制台输出应简洁,并带有进度指示
- 实时显示正在提取和保存的内容
原型屏幕:
- ⚠️ 原型屏幕始终使用子 Agent,以避免上下文膨胀
- 子 Agent 完成全部 3 项任务:获取 HTML → 提取图片 → 更新 URL
- 使用 Miro MCP 图片工具获取下载 URL,然后用 curl 将图片保存到磁盘
- 如果某张图片下载失败,记录警告,但继续处理其他图片
优先级:
- 优先处理文档、原型和表格(对规格最有价值)
- 图片不是可选项——如果存在原型屏幕,必须提取图片
背景
什么是 miro-spec?
miro-spec 插件可从 Miro 白板提取规格内容并保存到本地文件。这样 AI 就能在规划和实现过程中参考规格,而无需重复调用 API。
以下情况可使用它:
- 从 Miro 白板提取产品需求
- 保存设计规格以供实现
- 下载原型和图表以供参考
- 创建 Miro 文档的本地副本
- 离线处理规格或在版本控制中管理规格
内容类型
| 类型 | 保存为 | 包含内容 |
|---|---|---|
| 文档 | .md | 带格式的 Markdown 内容;保留标题和结构 |
| 图表 | .md | AI 生成的描述;流程分析和组件关系 |
| 原型容器 | .md(后缀为 -container) | 带导航图的 Markdown |
| 原型屏幕 | .html(后缀为 -screen) | 包含 UI 布局的 HTML 标记 |
| 表格 | .json | 结构化数据,包含列定义和所有行数据 |
| 画框 | .md | AI 对画框内容生成的摘要 |
| 图片 | .png | 从原型中自动提取;以 Miro 项目 ID 命名 |
白板 URL 与项目 URL
白板 URL — 提取完整规格。最适合全面提取所有相关文档和图表中的规格。它会列出白板上的所有项目,筛选与规格相关的类型,并逐项提取。
项目 URL — 提取单个文档、图表或原型屏幕。最适合定向提取或更新单个项目。处理单个项目时速度更快;使用 moveToWidget 参数。
图片的提取方式
- 插件扫描原型屏幕的 HTML 内容
- 查找
src属性中的 Miro 图片 URL - 使用该 URL 通过 Miro MCP 查找每张图片
- 通过 Miro MCP 下载每张图片
- 将原始 URL 替换为相对路径
原始 HTML:
<img src="https://miro.com/api/v2/boards/uXjVK123abc=/images/3458764612345"/>
提取后:
<img src="../images/3458764612345.png"/>
优势:图片可离线使用;查看文档无需调用 API;本地加载更快;提取后的文件夹可提交到版本控制中。
使用规格规划实现
提取规格后,用户可以让 AI 助手据此进行规划或实现。提示词示例:
- “查看
.miro/specs/documents/中的产品需求,并制定技术实现计划” - “参考
.miro/specs/diagrams/3458764612345.md中的架构图,并实现数据库架构” - “将我实现的身份验证流程与
.miro/specs/prototypes/3458764612346-screen.html中的规格进行比较”
AI 助手会在规划过程中自动读取相关文件。务必先检查 .miro/specs/index.json,了解已提取的内容。
最佳实践
提取策略:
- 使用白板 URL 进行初始全面提取
- 使用项目 URL 更新特定文档
- 开始实施前先提取
- 规格变更时重新提取
目录管理:
- 如果规格是临时的,请将
.miro/specs/保留在.gitignore中 - 如果要共享规格,请将其提交到版本控制
- 白板结构发生重大变化时,清理后重新提取
- 更新单个项目时,添加到现有内容中
使用规格:
- 始终先检查
index.json,了解可用内容 - 直接阅读 HTML 文件,查看完整的原型内容
- 使用 Markdown 文件快速查看图表概览
- 解析 JSON 文件,获取结构化表格数据
性能提示:
- 如果白板很大,可使用项目 URL 从特定画框中提取
- 清理旧的提取内容,避免混淆
- 谨慎使用白板 URL(处理大型白板可能较慢)
- 在不同的实施阶段之间缓存提取内容
故障排除
未从白板中提取到项目:
- 白板可能不包含文档、画框或表格项目
- 尝试使用项目 URL 获取特定内容
- 确认白板 URL 正确
图片未下载:
- 某些图片可能无法通过 MCP 访问
- 如果下载失败,将保留原始 URL
- 使用外部图片 URL 时,文档仍可阅读
提取后找不到文件:
- 检查
.miro/specs/index.json,确认实际路径 - 确认提取已成功完成
- 查看提取输出中的错误消息
大型白板耗时过长:
- 使用项目 URL 提取特定内容
- 单独提取画框,而不是整个白板
- 考虑按内容类型筛选
另请参阅
- 规格存储格式 — 详细的文件格式文档
- 插件 README — 安装和设置说明