关于 visual-plan
这项技能通过 `vplan` 命令行工具将结构化计划转换为可视化 MDX 页面,适合需要准备计划并收集反馈的人。它利用图表、时间线和表格呈现内容,并支持交互式审阅与修改。
主要功能
- 01MDX 计划编写指南
- 02图表、时间线和数据组件
- 03计划校验与质量检查
- 04支持评论和作答的交互审阅
- 05原位修改与变更标记
- 06静态页面、预览与导出选项
适用场景
- 01呈现产品发布计划
- 02审阅事件响应计划
- 03收集开放问题的决策
- 04将可视化计划导出为可分享文件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ brandonburrus/ visualplan --skill visual-plan安装后在 Claude Code 中输入/visual-plan确认已加载。
附带文件references/static-exports.md
详细介绍
目的
使用 vplan CLI 将计划呈现为可视化 MDX 页面,而不是一大段文字。组件的适用范围很广:虽然下面的示例偏向代码场景,但这些组件适用于任何结构化计划
(产品发布、研究议程、事件响应等),不只适用于软件变更。按需选用适合计划的组件,跳过不适用的组件。
最重要的是,展示,而非讲述:读者应能通过浏览图表、阶段和表格来理解计划,文字只负责串联视觉内容,而不是承载计划本身。下面的 展示,而非讲述一节是这项技能的核心。
如果找不到
vplan命令,请先全局安装:npm i -g vplan@latest(发布在 npm 上)。之后重新运行失败的命令。
工作流
-
将计划写入
.mdx文件,以单个# 标题开头(它会成为计划标题;不要添加 frontmatter)。然后使用下方的组件;它们始终处于作用域内,因此无需编写import语句。 -
展示给用户之前先验证:
vplan check <file>.mdx。修复所有报告的file:line:col问题(它会列出有效的枚举值,并标记未知组件)。check还会运行质量 lint,标记渲染效果较弱的内容(下文强制执行的 Gotchas);这些警告会导致check失败,因此也要修复。 -
使用
vplan <file>.mdx呈现计划。交互式审阅是交付计划的默认方式,不是专门用于最终签字确认的模式。它会打开带有反馈层的计划页面,用户可以对整个章节或选中的文本发表评论,直接回答任何<Questions>(每个问题都会变成内嵌答题框;带有嵌套选项项目符号的问题会变成可点击选项,所选选项的文本(或输入的“其他”文本)将作为答案,并以Answer to "<question>":的格式打印出来),然后点击 Approve / Deny / Iterate。它会一直阻塞,直到用户提交,然后将决定、评论和答案打印到 stdout 并退出:approve 为 0,deny 为 1,iterate 为 2,超时为 3(--timeout,默认 4h;关闭标签页会视为 deny)。--timeout后始终添加ms样式的单位(30s、45m、4h):裸数字会按毫秒读取,因此--timeout 240等待的是四分之一秒,而不是 240 分钟。它是一个长期运行的前台服务,因此请在后台运行。(显式的--review标记仍然有效,但现在审阅已是默认方式,因此不再需要。)评论可能带有严重程度标签:将[must-fix]评论视为阻塞项(计划获批前必须处理),将[suggestion]或未带标签的评论视为非阻塞意见。然后根据打印出的反馈采取行动:- Approve -> 按照计划继续。
- Iterate -> 根据每条评论修改计划,然后直接重新运行
vplan <file>.mdx;审阅标签页会就地更新同一份计划,轮次编号会自动递增(仅在需要覆盖时传入-i N)。重复此过程,直到 Approve 或 Deny。在原位置编辑同一个.mdx文件并重新渲染:vplan会为每份呈现的计划创建快照(以文件路径为键),因此下次渲染会自动通过细微的 git 差异标记和“N changed”摘要标出自上次查看以来的更改,让用户只需重新审阅差异部分。传入--diff <baseline.mdx>可与指定文件进行差异比较,而非使用快照;传入--no-diff可关闭差异比较(例如,首次查看时保持页面整洁)。 - Deny -> 停下并重新考虑;不要继续。
**对于所有非简单计划,审阅都是合适的默认方式。**有针对性的评论和内嵌
<Questions>答案,能比来回聊天更有效地推动计划改进;审阅循环最终会以明确的 Approve 收尾,确保计划已敲定。只有在用户只是想查看,而非塑造计划或作出决定时,才使用静态渲染(第 4 步)。 -
静态页面、实时重新加载预览或 PDF/JPG 导出是非审阅类输出,适用于用户只想查看计划,或想要可分享的文件而非进行审阅的情况。需要时,加载
references/static-exports.md;其中包含这些输出对应的命令和标记(为保持审阅为默认方式,这些内容未放在此处)。无论选择哪种输出,计划的编写方式(以下所有内容)都相同。
随时运行 vplan components,查看准确的 prop 签名。
组件
数据组件(FileTree、Chart、Stat、Compare、Matrix、Questions、Checklist)
将数据作为 Markdown 子内容接收,而不是作为属性传入:在标签之间编写普通 Markdown 列表(对于
Matrix 和多系列 Chart,则编写 Markdown 表格)。只有标量设置
(title、type、status)才是属性。这样所需的 token 更少,也能避免导致渲染失败的 {[{ ... }]}
花括号错误。
-
<Phase title="..." status="planned|active|done">:编号垂直时间线中的一个步骤;内部可包含 Markdown(有序列表、正文、嵌套组件)。步骤会按顺序自动编号。计划中的每个主要步骤使用一个。 -
```mermaid围栏代码块,用于绘制图表:架构(flowchart)、sequenceDiagram、 依赖关系图、stateDiagram-v2、classDiagram、erDiagram和xychart-beta。凡是结构性内容,优先使用 此方式。(不支持gantt和pie;定量数据请使用<Chart>。现在check会验证每个图表,因此不支持的类型会导致检查失败,并报告file:line:col,而不是渲染错误框。) -
<Svg src="./diagrams/power-path.svg" title="Power path" caption="Bench unit, splitter-fed" />: 内嵌已有的本地.svg文件中的图表,例如由其他工具导出的架构图或时序图。src相对于计划文件; 构建时会读取、净化并内嵌文件,因此页面可独立使用,且图表会适配页面的浅色/深色主题。title为屏幕阅读器和展开视图提供名称(导出 SVG 自带的<title>往往是工具默认值),caption则可在图表下方添加一行说明。它和 mermaid 图表一样,支持悬停展开/全屏查看。仅支持静态 SVG:<script>、<foreignObject>、事件处理程序(on*)以及任何外部引用(不是同一文档#fragment的href、src、url(...)或@import)都会被拒绝,而不是移除;check会在标签所在行报告原因。大小上限为 2 MB。仅当图表已存在于文件中时才使用此方式;若能用文本表达,请编写```mermaid图表。 -
```math围栏代码块,用于以 LaTeX 编写并排版为数学公式的展示公式(复杂度界、概率、线性代数)。示例:```math,然后写T(n) = O(n \log n)。 -
<Callout type="note|tip|risk|decision|warn">:突出显示风险、决策、提示或说明;内部可包含 Markdown。(note为蓝色,tip为绿色,decision为紫色,risk为红色,warn为黄色。) -
<FileTree>:文件变更映射。每个文件占一条项目,格式为- <change> <path>,其中change为add|modify|delete|move。移动操作需提供起点和终点:- move <from> -> <to>(文件显示在目标位置,并标明来源)。路径以/结尾表示整个目录(例如- delete src/legacy/)。系统会根据路径扩展名自动添加彩色文件类型图标。可在任意行末追加-- <note>,为该变更添加简短行内注释(说明其作用 或原因);请使用短语,因为注释会与文件名显示在同一行。<FileTree> - add src/gateway/rate-limiter.ts -- sliding-window check against Redis - modify src/gateway/middleware.ts -- mount the limiter behind the flag - delete src/gateway/legacy/ </FileTree> -
<Chart type="bar|line|area|scatter|radar|gauge|funnel|treemap|pie" title="...">: 用于估算值/指标。单系列:每个数据点占一条项目,格式为- <label>: <value>(数值)。 多系列(bar/line/area/radar):使用表格,表头为category | series1 | series2(第一个单元格之后的单元格用于命名系列,并作为图例;第一列为类别轴)。具体要求:scatter使用表格,且恰好包含两列数值,分别作为 x 和 y (| point | x | y |);pie/gauge/funnel/treemap始终为单系列,且只能使用列表形式(表格会被拒绝);gauge使用 0-100 刻度,funnel按降序排列。在多系列bar/area中添加stacked(<Chart type="bar" stacked>),即可使用堆叠而非分组显示。<Chart type="bar" title="Effort (days)"> - Limiter: 2 - Dashboards: 1 </Chart> <Chart type="line" title="Latency by stage (ms)"> | Stage | p50 | p95 | |-------|-----|-----| | Auth | 12 | 30 | | DB | 40 | 120 | </Chart> -
<Compare>:以优缺点卡片的形式并排权衡不同方案。每个选项使用一个## Name标题(在推荐选项后添加(pick)),后面跟任意数量的- pro:/- con:项目符号。<Compare> ## Redis sliding window (pick) - pro: accurate - pro: shared across nodes - con: network hop ## In-memory token bucket - pro: fast - con: per-node only </Compare> -
<Matrix>:比较网格(选项为列,评估标准为行),用于根据多个维度为多个选项打分。编写一个 Markdown 表格;第一列是行标签,并在一个列标题后添加(pick)以突出显示。优缺点使用<Compare>,评分表使用<Matrix>。<Matrix> | Dimension | Postgres (pick) | ClickHouse | DynamoDB | |-----------|-----------------|------------|----------| | Writes | medium | high | high | | Querying | high | medium | low | </Matrix> -
<Questions>:列出你希望读者在开始构建前解决的开放问题,每个项目符号一个问题。使用此组件,而不是将不确定事项埋在正文中。标题默认为「开放问题」;使用title="..."覆盖。在--review会话中,每个问题都可以直接作答,因此,如果你希望审阅者回答具体问题,优先使用<Questions>块,而不是正文。将项目符号嵌套在问题下方,可提供多选选项:在审阅过程中,这些选项会变成可点击的选项(另有一个「其他」自由文本字段),所选选项的文本会作为答案返回。只要能够列出可能的答案,就尽量提供选项;这样可以获得清晰、可执行的答案,而不是一段正文。没有嵌套项目符号的问题将以自由文本形式作答。<Questions> - Should the limiter fail open or fail closed if Redis is unreachable? - Fail open, availability first - Fail closed, safety first - Is a 15-minute access-token TTL acceptable? </Questions> -
<Checklist title="Done when">:验收标准 / 完成定义,使用 Markdown 任务列表:已完成用- [x],待办用- [ ]。<Checklist title="Done when"> - [x] Returns 429 over the limit - [ ] Dashboards live </Checklist> -
<Stat>:以卡片网格的形式展示计划的关键指标(变更文件数、预计正常运行时间、发布进度)。每个项目符号对应一张卡片,格式为- <label>: <value> (<intent>) -- <caption>,其中 intent 可以是note|good|warn|risk之一,(intent)和-- caption均为可选项。value 为自由文本(5 min、99.9%),而非数字。此组件用于静态数据,而非时间序列(时间序列请使用<Chart>)。只有当计划确实有值得突出的关键数字时,才添加<Stat>;大多数计划都没有,虚构或凑数的指标还不如完全省略该组件。<Stat> - Files changed: 12 - Est. uptime: 99.9% (good) - RPO: 5 min (risk) -- worst-case data loss </Stat> -
围栏代码块会进行语法高亮(Expressive Code):使用
```ts(或 js、json、bash、python、go、rust、sql、yaml 等)展示关键代码片段。使用```ts title="src/path/file.ts"添加文件名,在代码块上方显示文件名标题。 -
使用围栏元字符串中的 Expressive Code 属性标记代码块内的行和文本(无需组件)。标记分为三种类型:
mark(中性,默认)、ins(绿色,新增)和del(红色,删除)。每种类型都接受行号、范围、引号括起的字符串或/regex/。可用这些标记突出显示计划要修改的行。- 行 / 范围(中性):
```ts {2}、```ts {2-4}、```ts {1, 3, 5-6} - 类型化行:
```ts ins={3-4} del={2} mark={6}(可在同一个代码块中自由组合) - 行内文本:
```ts "TokenBucket",重命名可写作```ts del="oldName" ins="newName" - 正则表达式(以及捕获组):
```ts /\bTODO\b/、```ts ins=/const (\w+) =/(标记捕获组)
- 行 / 范围(中性):
展示,而非讲述
可视化计划的核心,是用读者扫一眼就能理解的内容,取代大段文字。默认优先使用组件,而非句子:如果某个事实具有结构,就把结构展示出来,不要用段落描述。文字只是连接视觉元素的纽带,而不是主体内容。
- 先展示结构。 开篇最多用一段文字交代背景,接着给出
```mermaid架构图(如果图已作为文件存在,则使用<Svg>),然后是<Phase>时间线。读者应在读完整句子之前,就能了解计划的整体结构。 - 优先用图表或
<FileTree>展示结构,而非用文字描述。 展示数据路径的流程图胜过追踪路径的段落;展示文件变更的文件树胜过列出文件的句子。 - 将含义从文字移至承载它的组件中。 风险和决策放入
<Callout>,待解决的问题放入<Questions>,权衡放入<Compare>/<Matrix>,验收标准放入<Checklist>,不要埋在容易被扫读略过的段落里。 - 精简阶段中的文字。
<Phase>是一个步骤,不是篇文章:用一两行说明意图,然后展示视觉内容。视觉内容才是重点。 - 展示适量内容。 大型工作以图表和多个阶段开篇;涉及两三个文件的变更,可能只需要简短的
<FileTree>和<Checklist>。不要添加没有信息量的图表或阶段:空洞的两节点流程图毫无意义,还不如一句普通说明。只有在存在结构时才展示;否则,一句简洁的说明就够了(<Stat>也适用,具体说明见其对应条目)。
编写计划
<Phase>和<Callout>可以包裹任意 Markdown 内容和组件:<FileTree>、<Chart>、<Matrix>、```mermaid图表、代码块或- [ ]任务列表都可以嵌套其中。可自由嵌套,将相关内容归入某个步骤或重点说明。- 图表、图形和
<Svg>都会渲染一个悬停时显示的“展开”按钮,打开后可在全屏视图中缩放和平移,因此即使内嵌显示时缩小,密集图表也仍然清晰易读(代码块除外)。对于确实很大的图表,可以借助此功能;但如果内嵌视图必须独立呈现,将其拆分成较小的图表仍然更易阅读。
规则
- 面向用户的计划绝不能使用
--no-open。 计划的目的就是让用户看到;审核会话会自动打开。只有在明确要求无头/CI 执行时,才使用--no-open。 - 不使用图片或外部资源。 页面是一个独立的自包含文件,因此无法嵌入 Markdown 图片(
)或任何外部资源,而且check会拒绝 Markdown 图片。可视化内容使用```mermaid图表;如果图表已作为本地.svg文件存在,则使用<Svg>(构建时会内联,因此不属于外部资源);也可以用文字描述。
注意事项
其中一些问题(大段纯文本、过宽的 LR mermaid 图、过长的 Matrix 单元格、带注释的 FileTree 移动行,以及缩放差异极大的 Chart)现已由 check 质量 lint 强制检查,出现这些问题会导致检查失败。因此,这些是硬性规则,而不只是风格建议。
<、{和}在 MDX 中属于语法。 裸写的<Thing>或{value}可能导致渲染失败。请将字面量尖括号、花括号、泛型(List<T>)或类似标签的文本放在反引号或代码围栏中,确保每个字符都安全且按字面呈现。- 原始内联 HTML 标签会导致
check失败。<kbd>、<sub>、<sup>、<details>等会被识别为未知组件并导致失败;请改用反引号或纯文本。除此之外,普通 Markdown 也可以与这些组件搭配使用:GFM 表格(<Matrix>/<Chart>之外)、引用、脚注、~~删除线~~、自动链接、- [ ]任务列表,以及自定义起始编号的有序列表都能正常渲染。 <Chart>展示的是数据形态,而非精确数值。 图表没有柱上的数值标签,因此读者必须精确掌握的数字也应写在正文中。标签请控制在一两个词以内(过长的横轴标签可能会被省略或挤在一起),并且切勿在同一张图表中放入数量级相差悬殊的数据系列:接近 50 的数值与接近 2,000,000 的数值共用同一条 y 轴,会使较小的数据系列被压平在零线附近。请拆分为多张图表,或统一使用相同单位。<Matrix>单元格不会自动换行。 单元格中的长句会导致出现水平滚动条,并将其他列挤出屏幕。单元格内容请限制为一个词或简短评分;理由应写在正文或<Callout>中,而不是放在单元格里。- 避免在
<FileTree>的move行中使用-- 注释。 移动操作会显示源路径(← <from>注记),占用该行的大部分宽度,因此同一行的注释会显得拥挤。请不要在移动行中添加注释,将说明放在正文或<Callout>中;-- 注释仅用于有足够空间的添加、修改和删除行。 - 过宽的 mermaid 图会缩小到难以辨认。 节点较多时,优先使用自上而下的布局(
flowchart TD);过长的从左到右(LR)链会缩小以适应页面,导致内联显示时几乎无法阅读。请将大型流程拆分为几张较小的图,而不是绘制一张庞大的图。