stack-diagram 是做什么的?
Hermes 集成
将 <skill> 解析为此 SKILL.md 所在的目录,而不是项目工作目录。使用带引号的绝对路径,通过 terminal 运行打包在 scripts/ 中的 Python 脚本。使用 read_file 读取模板/参考文件,使用 write_file/patch 写入生成的文件。建议为 Playwright 使用独立的 Python 环境;仅导入不能证明浏览器驱动正常工作。
对于基于仓库的请求,首先记录节点和边的证据。依赖关系不能确定运行时拓扑。将推断出的关系标记为假设;当歧义会影响架构时,应进行询问。用户明确提供的拓扑是证据。绝不要读取机密文件或不相关文件来发现技术栈。
使用 MEDIA:/绝对/路径/to/out.html 和 MEDIA:/绝对/路径/to/out.png(加上深色 PNG 版本)交付本地文件;使用 vision_analyze 检查两种主题的渲染效果。HTML 是唯一的视觉真相来源;PNG 来自 Chromium,而非独立的 SVG/PIL 渲染器。在文件实际存在之前不要标记为已交付。此技能不会调用或修改 brag。仅当请求视频时才使用 stack-video;它是一个独立的兄弟技能,不是必需的步骤。
上游脚本/资源来自 caru-ini/stack-diagram;请参见此包的 UPSTREAM.md。可选的画廊指南仍需用户明确同意;安装或发布此包不等于同意使用画廊。
生成工程制图风格的架构图:白色瓷砖上的真实品牌 Logo、带标签的分组框(类似云厂商 VPC 图)、使用等宽字体标签的正交箭头,在冷色调的方格纸背景上。一个自包含的 HTML 文件是真相来源;PNG / TSX / 其他产物都基于它生成。
要求
- Python 3.9+(
fetch_icons.py、build.py和share.py仅使用标准库) - 获取图标时需要网络访问图标源(svgl.app、raw.githubusercontent.com、cdn.jsdelivr.net、aws.amazon.com 和 d1.awsstatic.com 用于 AWS 图标、services.google.com 用于 Google Cloud 图标、learn.microsoft.com 和 arch-center.azureedge.net 用于 Azure 图标,以及品牌的官方网站或仓库用于
name=URL) - Playwright + Chromium 用于
render_png.py:pip install playwright && python3 -m playwright install --with-deps chromium
工作流程
- 确定内容(节点、组、边)
- 获取图标 —
scripts/fetch_icons.py - 规划坐标 — 阅读
references/geometry.md - 从
assets/template.html构建 HTML —scripts/build.py - 渲染 PNG 并查看结果,然后再交付
- 以请求的格式交付
- 可选择将其分享到公共画廊
步骤 1 — 内容
根据用户列出的技术/服务,确定:
- 节点:每个技术 = 一个节点(名称 + 简短的小写角色,如
http server、sqlite db) - 组:为共享运行时、供应商或仓库的内容绘制一个框(例如,一个云供应商框包含一个运行时框;一个包含工具的单体仓库框)。嵌套一层是可以的;更深则显得杂乱。使用品牌自身的首字母大小写编写组标签(
GitHub、npm);模板会按原样显示。 - 边,三种类型:
- 强调色实线 = 主要的请求/数据流(最佳效果是使用一条连续的路径)
- 中性色实线 = 次要的内部连接
- 中性色虚线 = 开发/部署时的关系(CI、git hooks、IaC 部署)
如果用户只提供了一个扁平的工具列表,根据这些工具的用途推断合理的组和流程 — 仅当某个工具的歧义会导致图表无论哪种方式都错误时才进行询问。
步骤 2 — 图标
python3 scripts/fetch_icons.py <icons-dir> tanstack hono drizzle "betterauth:better-auth" "orpc=https://orpc.unnoq.com/logo.webp"
python3 scripts/fetch_icons.py <icons-dir> "aws:aws/AWS-Cloud-logo" "vpc:aws/vpc" "fargate:aws/fargate" "s3:aws/s3"
python3 scripts/fetch_icons.py <icons-dir> "gcp:google-cloud" "run:gcp/cloud-run" "lb:gcp/load-balancing" "sql:gcp/cloud-sql"
python3 scripts/fetch_icons.py <icons-dir> "azure:azure/Azure-A" "app:azure/app-service" "vnet:azure/vnet" "sql:azure/sql-database"
规范格式:name(名称用作 slug)、name:slug(不同的 slug)、name=URL(显式 URL)、name:aws/<Name>(官方 AWS 图标)、name:gcp/<Product>(官方 Google Cloud 图标)、name:azure/<Name>(官方 Azure 图标)。脚本按顺序尝试以下来源:svgl → devicon → gilbarbara/logos,写入文件以及 manifest.json,并标记填充为白色的图标。svgl(svgl.app)排在第一位,因为它提供了现代开发品牌(TanStack、Better Auth、Hono...)当前官方的标识。当 Logo 有浅色/深色版本时,浅色版本保存为 <name>(在两种主题中磁砖都是白色),深色版本保存为 <name>_dark 用于组标签。svgl 仅通过精确标题匹配,因此未命中会直接跳过。其 API 还暴露了 wordmark 变体 — 偶尔对宽组标签有用,但绝不用于磁砖。
比机制更重要的规则:
- 绝不要重新着色 Logo。 用户会注意到。如果 Logo 是白色或对于白色磁砖来说太浅,请将其放在深色磁砖(
tile dark类)上,而不是修改其填充。清单中的white_fill标志是一个启发式规则 — 白色填充可能是彩色标志上的内部细节(tRPC、Ubuntu),因此在使用深色磁砖之前,请查看 SVG。 - 仅使用官方标志。 simple-icons 故意不作为来源:其字形是单色重绘,用户一眼就会看出问题。当所有来源都未找到时(
FAIL),找到官方文件并将其作为name=URL传递 — 在项目的仓库(根目录下的logo*.svg、docs/、assets/、public/)和其网站(/logo.svg、/favicon.svg、/images/logo.svg)上查找。某些标志仅存在于仓库中(Lefthook 的标志是evilmartians/lefthook根目录下的logo_sign.svg)。 - 抽象概念使用象形图,而不是文本。 像“开发环境”、“cron”、“队列”、“缓存”或“webhook 接收器”这样的节点没有品牌 — 通过
name:lucide/<icon>使用 Lucide 线条图标(例如devenv:lucide/terminal、cron:lucide/clock;浏览 lucide.dev/icons)。不要使用磁砖中的文本或 Emoji。 - 供应商子产品(Cloudflare D1/R2/KV...)通常没有独立的 Logo:只需在磁砖上重复使用供应商的 Logo,让节点名称来区分(“Cloudflare D1” / “sqlite db”)。
- AWS 使用 AWS 自己的图标。 每个服务都有一个:使用
name:aws/<Name>获取,运行时从 AWS 的官方图标包中读取(例如lambda:aws/lambda、aws:aws/AWS-Cloud-logo、s3:aws/s3)。AWS-/Amazon-前缀是可选的,常用缩写有效(s3、sqs、sns、ses、ecs、eks、ecr、elb、alb、nlb、iam、kms、msk、vpc),如果输入错误会打印所有名称。slugaws、amazonwebservices和aws-*指向同一个包,该包没有的图标会FAIL而不是回退到第三方副本。对于服务,始终编写aws/前缀:单独的dynamodb将通过第三方链获取。将包和松散图标文件排除在仓库之外:AWS 允许在图表中使用图标,但重新分发未获确认。 - AWS 区域遵循 AWS 自身的绘制规则。 服务图标带有自己的方形背景,可以在浅色和深色背景上工作,因此使用
tile bare:白色磁砖只会加倍边框。其内部的人员和通用节点使用 AWS 的通用图标(user:aws/General-User;还有General-Users、General-Client、General-Internet、General-Server),使用tile bare res并配合模板的lt/dk对。组使用模板的group aws表示 AWS Cloud(标签中带有aws:aws/AWS-Cloud-logo),加上region、az、vpc、private或public表示其余部分:方角、仅轮廓、标签使用墨水色、无供应商色调,并且在角落内嵌一个 30px 图标而非 14px 图标。在 VPC 内部,当你知道或可以安全推断出拆分方式时(面向互联网的负载均衡器在公共子网;应用服务器和数据库在私有子网),显示公共和私有子网:平坦的 VPC 是 AWS 人员首先注意到的。其内部的边使用一种颜色和开放箭头:<path class="aws" ... marker-end="url(#open)"/>,aws dash用于开发/部署,普通的.el标签,并且没有图例。将节点命名为Amazon S3/AWS Fargate,而不是简单的S3/Fargate;像ALB这样的简短形式放在角色行中,全名(Elastic Load Balancing)下方。名称可以占两行,但Amazon/AWS必须保持在第一个单词行:如果在紧跟前缀后换行,则加宽该节点(left:<centerX-76>px; width:152px)。 - Google Cloud 使用 Google 自己的图标。 使用
name:gcp/<Product>获取,运行时从 Google 的官方包中读取(例如run:gcp/cloud-run、lb:gcp/load-balancing、memorystore:gcp/memorystore)。只有核心产品有自己的图标(Cloud Run、Cloud SQL、Cloud Storage、BigQuery、GKE、Compute Engine、Vertex AI...)。每个其他产品都使用其类别的图标,如 Google 指南所指定:Cloud Load Balancing 和 Cloud CDN 都使用 Networking,Memorystore 和 Firestore 都使用 Databases。编写产品名称,脚本会选择图标。Cloud/Google前缀是可选的,某些简短形式有效(vpc、iam、kms、iap、gce、gcs),如果输入错误会打印所有名称。gcp/storage是 Storage 类别;Cloud Storage 是gcp/cloud-storage。sluggcp-*和google-cloud-*指向同一个包,该包没有的图标会FAIL而不是回退到第三方副本:这些副本是已退役的六边形图标,Google 表示不应使用。对于产品,始终编写gcp/前缀:单独的bigquery将通过第三方链获取。gcp:google-cloud是用于组标签的 Google Cloud 标志。Gemini 和 Firebase 不在包中:使用简单的gemini和firebase。将包和松散图标文件排除在仓库之外:Google 提供图标用于图表和文档,重新分发未获确认。 - Google Cloud 图表保持正常风格,使用 Google 的组。 Google 自己的图表(纯蓝色面板、水平卡片)故意不被复制:图标放在普通的白色磁砖上,边和图例保持不变。组使用模板的
group gcp表示 Google Cloud(标签中带有gcp:google-cloud),加上vpc、region、subnet或zone。VPC 是全局的,子网是区域性的,因此将区域放在 VPC 内部,永远不要将 VPC 放在区域内部。全局和无服务器服务(外部负载均衡器、Cloud Storage、Cloud Run)保持在 VPC 外部。由于图标是共享的,始终编写产品的全名(Cloud Load Balancing,而不是LB),并加宽名称会换行的节点(left:<centerX-76>px; width:152px)。 - Azure 使用 Microsoft 自己的图标。 每个服务都有一个:使用
name:azure/<Name>获取,运行时从 Microsoft 的官方包中读取(例如app:azure/app-service、azure:azure/Azure-A、vault:azure/key-vault)。Azure-/Microsoft-前缀和复数s是可选的,常用简短形式有效(aks、vm、vnet、nsg、waf、blob、cosmos、redis、postgres、functions、front-door、apim、ai-search),如果输入错误会打印所有名称。slugazure、microsoft-azure和azure-*指向同一个包,该包没有的图标会FAIL而不是回退到第三方副本。对于服务,始终编写azure/前缀:单独的cosmos将通过第三方链获取。Microsoft Entra ID 有独立的图标集:将其官方文件作为name=URL传递。Microsoft 仅允许在架构图、培训材料和文档中使用这些图标。切勿裁剪、翻转、旋转或重塑图标,仅将其用于其代表的 Microsoft 服务,并将包和松散图标文件排除在仓库之外。 - Azure 图表保持正常风格,使用 Microsoft 的组颜色。 Microsoft 自己的图表故意不被复制:图标放在普通的白色磁砖上,边和图例保持不变。组使用模板的
group azure表示 Azure(标签中带有azure:azure/Azure-A),加上rg、region、vnet、subnet或zone,并且vnet或subnet标签带其图标(vnet:azure/vnet、subnet:azure/subnet)。VNet 属于一个区域,因此它放在区域内部。像 Front Door 这样的全局服务保持在区域外部。App Service 除非在 App Service 环境中运行,否则位于 VNet 外部,通过私有端点访问的 PaaS 服务可以放在 VNet 内部,其角色为private endpoint。Microsoft 要求在每个图标旁边提供服务全名(Azure SQL Database,而不是SQL),因此加宽名称会换行的节点(left:<centerX-76>px; width:152px)。 - 供应商规则仅覆盖其自身区域。 AWS、Google Cloud 和 Azure 的规则仅适用于该供应商组内部,即使图表中未显示其他内容。其外部的所有内容,例如旁边的用户或跨越进入其中的边,都保持正常的磁砖、组、边和图例。
- 非品牌节点(用户、浏览器、互联网、设备、裸金属服务器):从
assets/generic/复制一个图形到节点名称下的图标目录,或者使用name:lucide/<icon>— 不要使用 Emoji。这些不是品牌 Logo,因此将其着色为图表的墨水色是可以的(获取脚本会自动为 Lucide 图标执行此操作)。 - 组标签图标以 14px 渲染 — 它们需要方形图形标记。文字标记和宽锁码在这么小的尺寸下会变得模糊;如果主图标是文字标记,请单独获取品牌的方形图标用于标签(svgl 通常有;否则是项目自己的图标或 favicon 文件)。
- 组标签位于组的色调上,而不是白色磁砖上,因此在深色主题中,带有黑色部分的标记会在那里消失。如果
fetch_icons.py保存了<name>_dark,则在标签中使用模板的lt/dk对;如果没有深色变体且标记有黑色部分,则在标签的<img>上添加plate类(仅深色主题白色衬底)。 - 光栅 Logo(png/webp)是可以的;构建脚本会创建 HTML。