Communitygithub.com

gustavorana25/c4-plan

架构的C4风格可视化层,以可导航的跳转式图表呈现。支持两种用法:(1)实现计划:在计划存在且执行前,让人查看计划如何影响现有系统、提问并在聊天中批准前请求变更;(2)从代码记录当前系统,用于新成员入职或理解仓库。

c4-plan 是什么?

C4 Plan 技能提供了一个基于C4模型的架构可视化层,生成可导航的交互式图表。它不替代计划,而是为计划添加视觉层和简要执行摘要。该技能支持“计划模式”和“系统模式”:在计划模式下,将实现计划转化为YAML结构(包含元素、状态、步骤、流程和约束),生成唯一链接供人类查看和评论;在系统模式下,从代码逆向工程出当前架构图。人类通过图表评论提出问题和变更请求,AI在聊天中回应并更新YAML,确保聊天为真相源。批准后生成Markdown摘要指导实现。支持C4层次(人员、系统、容器、数据库、队列、组件、代码),并可扩展到子层级。

兼容平台✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/gustavorana25/c4-model-skill/tree/HEAD

在你喜欢的 AI 中提问

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

文档

C4 Plan

人类理解计划的结构和边界;AI在聊天中批准后执行。此技能不替代计划:它生成计划的视觉层和执行的简要摘要。

它也可以记录当前系统(kind: system):相同的图表和流程,没有状态、步骤或审批。请参见第5节。

聊天是真相的来源。 查看器仅显示计划:人类无法在那里编辑任何内容。问题和变更请求作为评论(或粘贴到聊天中)传来,你在聊天中回应,所有变更都通过YAML进行。

你从不编写HTML或手动构建URL。你编写一个YAML;脚本进行验证、生成链接和简要摘要。

计划 ─► arch.yaml ─► 编码 ─► 链接 ─► 人类查看并评论 ─► 你调整YAML ─► 在聊天中批准 ─► 简要摘要 ─► 执行

脚本:python3 <skill-dir>/scripts/arch_url.py(仅使用标准库 + PyYAML;jsonschema 可选)。

1. 从计划生成 arch.yaml

保存到计划旁边,命名为 <plan-name>.arch.yaml。模式:schema/arch.v1.json。完整示例:examples/pix.arch.yaml。

规则:

  • 这是计划的架构,而非整个系统的架构。 包括计划创建、更改或删除的内容,以及理解所需的最小上下文(谁调用、谁被调用)。不要建模整个系统。
  • status:new / changed / removed / unchanged(默认)。上下文元素保持 unchanged。
  • C4层次:根级为 person、system、external;container、database、queue 在 system 内(或根级);component 在 container、database(表、迁移)或 queue(事件)内;code 仅在 component 内。
  • 计划创建或更改的所有内容都会深入到底层代码。 每个 system、container、database、queue 和 component,若 status 为 new/changed,则必须有 children,向下深入直到 code(validate 会在缺失时发出警告)。未更改的内容保持封闭:那是上下文。
  • 第4级(code):计划创建或更改的文件、类、模块或函数,带有 path。已存在且发生更改的文件为 status: changed。列出更改的内容,而不是组件的全部代码(每个组件2到4个通常足够)。
  • 关系连接最具体的元素(当存在时使用 code→code)。查看器会向上聚合到更高层级。
  • steps:每个计划步骤一个,顺序和标题相同。touches = 该步骤创建或更改的元素。
  • flows:计划后系统如何工作(steps 说明构建顺序;flows 说明执行顺序)。1到3个流程:主路径和最重要的失败路径(例如:“客户通过PIX支付”、“QR码过期”)。每个 hops[] 为 {from, to, label},并且必须遵循现有的关系,沿其方向或相反方向用于响应。使用最具体的元素(code),并将 label 写为发生的事件(“保存 txid 后再调用 PSP”),而不是关系名称。查看器会自动下降到每个跳转的级别。
  • constraints:实现必须遵守的规则,例如可验证的规则(“基于 txid 的幂等性”、“增量迁移,无表锁定”),而不是描述。仅在有重要决策的地方放置:合约、与外部系统的边界、安全、数据、迁移、核心业务规则。没有约束的内容在执行时由你自行决定。
  • 如果仓库中存在合约,请在 relations[].contract 中引用。

2. 验证并提供链接

python3 scripts/arch_url.py encode <plan>.arch.yaml
  • 错误:修正YAML并重新运行。不通过验证不要提供链接。
  • 警告:如果合理则修正(例如:新内容未深入到底层代码)。
  • 向人类提供链接,一行,并附上计划更改内容的简短摘要(例如:“3个新元素,2个已修改”)。告知他可以按 C(或评论),点击卡片并提问或请求更改,并且批准是在此聊天中进行的。

查看器:encode 生成已发布版本的链接,https://gustavorana25.github.io/c4-model-skill/(静态;计划位于 #hash 中,不会发送到服务器)。$C4PLAN_VIEWER_URL 可更改主机,--local 使用本地构建 viewer/dist/index.html(仅用于测试查看器本身的更改)。

2b. 如果你有嵌入式浏览器:监听页面

如果你拥有浏览器工具(Claude Code 的浏览器面板、Cursor 的浏览器、Chrome 中的 Claude),在那里打开链接而不是仅提供它,并在人类查看计划时监听页面。

聊天是真相的来源。 页面只是一个捷径:人类指向一个或多个卡片并评论,你在聊天中响应,绝不在页面中。你在页面中唯一更改的是计划,使用 load(),当对话改变结构时。

按原样打开 encode 生成的链接:它已经是 https://。(使用 --local 时,通过 http:// 提供 viewer/dist/,例如:python3 -m http.server;某些嵌入式浏览器会丢弃 file:// 链接的 #hash。)

页面暴露 window.c4plan(使用浏览器的JavaScript工具运行):

调用作用
await c4plan.next(30000)等待最多30秒以获取下一个事件。返回事件或 null。最大值为40秒(工具在大约45秒处截断)。
await c4plan.state()当前状态:url、plan、focus(打开的级别)、selected(人类正在查看的内容)、idleMs(他不再操作页面的时长)、doc。
c4plan.load(urlOrHash)替换图表为新版本,无需重新加载页面。
c4plan.stop()通知页面你已停止监听。

next() 的事件:

  • {event:"comment", targets:[{id,name}], view, text}:人类对这些元素发表了评论(可以是零个、一个或多个;view 是打开的级别)。在聊天中回复,以名称开头:“关于 API Pix 和 清算队列:…”。如果是变更请求,则修改YAML、运行 encode、调用 load(newLink) 并在聊天中说明更改内容。然后继续监听。
  • {event:"stop", reason:"idle"}:人类有10分钟未操作页面,监听自动结束。说出停止语句(步骤3)并退出循环。

循环:

  1. 开始前,在聊天中说一行:"我已在浏览器中打开图表,并在您操作时监听。按 C(或评论)、点击卡片并书写:我在此处回复。当一切就绪时,请在此告诉我批准。" 如果没有此警告,人类会操作页面,聊天中无任何内容出现,并且他不知道发生了什么。
  2. 重复 await c4plan.next(30000) 并处理每个事件。null 仅表示“尚无事件”:再次调用,无需在聊天中评论。监听持续时间取决于人类与页面的交互(每次点击、按键或滚动都会重置时钟);由页面决定结束时间,使用 stop。
  3. 在 stop 到达时停止。在 stop 时,在聊天中说:"我已停止监听图表,因为页面已闲置。请在聊天中评论何时需要,或要求我再次监听。" 如果你因其他原因需要提前停止,调用 c4plan.stop() 并说出相同内容。
  4. 如果在监听时人类在聊天中发送消息,则循环结束:回复该消息。然后读取 (await c4plan.state()).idleMs:如果小于10分钟,他仍在页面中,因此返回循环,无需再次警告。如果他批准,调用 c4plan.stop() 并继续第3节。
  5. 如果人类在聊天中询问关于“这个”或“这个元素”,读取 state().selected 以了解他在说什么。
  6. 在没有你监听的情况下,评论按钮会复制类似 关于 "API Pix" (pix-api) 在图表中:… 的文本供人类粘贴到聊天中。括号中的 id 是 YAML 中的 id。

3. 当人类在聊天中批准时

只有他能批准,且仅在聊天中(“已批准”、“可以继续”、“好的,执行”)。沉默、监听结束或无评论不等于批准。

  1. 在 <plan>.arch.yaml 中标记 approved: true 并从文件生成简要摘要:
    python3 scripts/arch_url.py brief <plan>.arch.yaml -o <plan>.arch.md
    
  2. 用几行总结自第一个链接以来对话中发生的变化(约束、结构、流程)。
  3. 在计划中添加对 <plan>.arch.md 的引用,然后继续执行。

如果人类粘贴查看器的链接(例如,在普通浏览器中打开),它仅用于查看:有效的版本是你的 <plan>.arch.yaml。

4. 遵守简要摘要执行

<plan>.arch.md 在执行期间是必需的:

  • 遵守结构(元素、关系、流程)和所有约束。如果实现要求更改结构或违反约束,停止并询问。
  • 引用的合约(contract)未经询问不得更改。
  • 在约束之外,优先采用最简单的方式并遵循现有代码的模式。
  • 人类在聊天中的要求优先于你的原始提议。
  • 最后,将实现的内容与YAML进行比较并报告差异(未预料到的新组件、关系之外的依赖、已更改的合约)。

5. 记录当前系统(kind: system)

当请求是理解或记录已存在的内容时(“记录架构”、“这个系统如何工作”、入职),没有计划:你读取仓库并生成带有 kind: system 的相同YAML。完整示例:examples/loja.arch.yaml。

version: 1
kind: system
title: 在线商店
description: 关于系统功能的一两句话。

如何构建:

  • 在编写之前先阅读。 入口点(路由、处理器、消费者、任务)、清单(package.json、docker-compose、基础设施)、迁移和外部服务客户端指示了容器、数据库、队列和外部服务。不要发明代码中未显示的组件;如果某些内容不确定,在聊天中说明。
  • 没有 status、steps 和 approved。 所有内容都是系统的当前状态(validate 会在任何残留时发出警告)。
  • 流程是最重要的。 2到4个:对业务最重要的路径、主要的后台任务和最常见的失败案例。通过它们,新来人可以理解系统。
  • 深度: 仅在流程穿越的地方深入到底层 code,带有真实的 path(确认文件存在)。其余部分保持为 container 或 component,封闭。
  • constraints 变成团队规则,需要修改的人必须知道(幂等性、谁可以写入哪个表、不可更改的合约)。
  • 关系和流程遵循与计划相同的规则(第1节)。

交付:像计划一样使用 encode 生成链接。用一行说明系统包含的内容(“5个容器、2个外部系统、2个流程”),并说明可以在“流程”选项卡中跟踪流程并用 C 提问。如果有浏览器,监听页面(第2b节):评论是问题,你在聊天中回答,或是对文档的修正,你将其应用于YAML并用 load() 重新加载。

对于仓库中可版本化的文本,brief 生成Markdown文档(元素、关系和流程):

python3 scripts/arch_url.py brief docs/architecture.arch.yaml -o docs/architecture.md

稍后,关于该系统的计划可以基于此YAML:复制,将 kind 改为 plan 并用 status 标记更改的内容。

相关技能