stack-diagram 是做什麼的?
Hermes 整合
將 <skill> 解析為包含此 SKILL.md 的目錄,而非專案工作目錄。透過 terminal 使用 Python 執行綑綁的腳本,並使用引號括起來的絕對路徑。使用 read_file 讀取範本/參考檔案,並使用 write_file/patch 寫入成品。建議為 Playwright 建立一個隔離的 Python 環境;僅匯入並不能證明其瀏覽器驅動程式能正常運作。
對於基於儲存庫的要求,請先記錄節點和邊的證據。相依性本身無法建立執行期拓撲。將推斷出的關係保持標記為假設;當模糊性會改變架構時,請提出疑問。使用者明確提供的拓撲即為證據。絕不要讀取機密或不相關的檔案來發現堆疊。
使用 MEDIA:/absolute/path/to/out.html 和 MEDIA:/absolute/path/to/out.png(加上深色 PNG)傳遞本地檔案;使用 vision_analyze 檢查兩種渲染主題。HTML 是唯一的視覺真相來源;PNG 來自 Chromium,而非獨立的 SVG/PIL 渲染器。在檔案實際存在之前,不要將其標記為已傳遞。此技能不會呼叫或修改 brag。僅在要求影片時才使用 stack-video;它是一個獨立的兄弟技能,不是必備步驟。
上游腳本/資源保留自 caru-ini/stack-diagram;請參閱此套件的 UPSTREAM.md。以下可選的藝廊說明仍需獲得使用者明確同意;安裝或發布此套件不代表同意使用藝廊。
產生工程繪圖風格的架構圖表:白色磁磚上的真實標誌、帶標籤的群組框(如同雲端供應商的 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指定的品牌官方網站或儲存庫) - 使用
render_png.py需要 Playwright + Chromium: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...)的當前官方標誌。當標誌有淺色/深色版本時,淺色版本會存為 <name>(兩種主題的磁磚都是白色),深色版本則存為 <name>_dark,用於群組標籤。svgl 僅透過精確標題匹配,所以未命中只會繼續往下嘗試。其 API 也公開了 wordmark 變體 — 偶爾可用於寬群組標籤,絕不用於磁磚。
比機制更重要的規則:
- 永遠不要重新為標誌著色。 使用者會注意到。如果標誌是白色的,或者對白色磁磚來說太淺,請將其放在深色磁磚上(
tile darkclass),而不是修改其填充色。manifest 中的white_fill標記是一個啟發式方法 — 白色填充可能是彩色標記上的內部細節(tRPC、Ubuntu),因此在考慮使用深色磁磚之前,請先檢查 SVG。 - 僅使用官方標誌。 simple-icons 特意不被包含為來源:其字形是單色重繪,使用者一看就知道不對。當所有來源都遺漏時(
FAIL),找到官方檔案並以name=URL傳遞 — 在專案的儲存庫(根目錄logo*.svg、docs/、assets/、public/)和其網站(/logo.svg、/favicon.svg、/images/logo.svg)中尋找。有些標誌僅存在於儲存庫中(Lefthook 的標誌是logo_sign.svg,位於evilmartians/lefthook的根目錄)。 - 抽象概念使用圖示,而非文字。 像是「開發環境」、「cron」、「佇列」、「快取」或「Webhook 接收器」這類節點沒有品牌 — 請透過
name:lucide/<icon>使用 Lucide 線條圖示(例如devenv:lucide/terminal、cron:lucide/clock;請參閱 lucide.dev/icons)。不要使用磁磚內的文字或表情符號。 - 供應商子產品(Cloudflare D1/R2/KV...)通常沒有獨特的標誌:只需在磁磚上重複使用供應商標誌,並讓節點名稱來區分即可(「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 位於 VNet 外部,除非它在 App Service Environment 中執行;透過 Private Endpoint 存取的 PaaS 服務可以放在 VNet 內部,並將其角色設定為private endpoint。Microsoft 要求每個圖示旁應有服務的完整名稱(Azure SQL Database,而非SQL),因此請加寬名稱會換行的節點(left:<centerX-76>px; width:152px)。 - 供應商的規則僅涵蓋其自身區域。 AWS、Google Cloud 和 Azure 的規則僅適用於該供應商群組內部,即使圖表中沒有其他內容也是如此。其外部的一切,例如其旁的使用者或穿越其中的邊,則保持使用正常的磁磚、群組、邊和圖例。
- 非品牌節點(使用者、瀏覽器、網際網路、裝置、裸機伺服器):從
assets/generic/複製一個字形到圖示目錄中,並以節點名稱命名,或使用name:lucide/<icon>— 不要使用表情符號。這些不是品牌標誌,因此將其著色為圖表的墨水色是可以的(fetch 腳本會為 Lucide 自動執行此操作)。 - 群組標籤圖示以 14px 渲染 — 它們需要一個方形字形標記。文字標誌和寬的鎖定型標誌在這種尺寸下會變得模糊;如果主要圖示是文字標誌,請為標籤單獨擷取品牌的方形圖示(svgl 通常有;否則使用專案自身的圖示或 favicon 檔案)。
- 群組標籤位於群組的色調上,而非白色磁磚上,因此在深色主題中,帶有黑色部分的標誌會在那裡消失。如果
fetch_icons.py儲存了<name>_dark,請在標籤中使用範本的lt/dk配對;如果沒有深色變體且標誌帶有黑色部分,請在標籤的<img>上添加plateclass(僅限深色主題,白色背景)。 - 點陣圖標誌(png/webp)是可以的;捕獲腳本會將其作為
name=URL傳入。 - 在 AWS/Google/Azure 群組內,圖示位於磁磚上,而非裸露。 例外情況是:當群組標籤使用該供應商的方形標誌(AWS 雲端、Azure A)時,該標誌位於群組角落,而不是位於磁磚上。
- 如果品牌方形標誌不存在,群組標籤會顯示文字。這並非理想情況,但可以接受。
- 使用
name:lucide/<icon>的抽象概念會自動符合顏色;品牌圖示則不會。
如果一個圖示在所有來源中都失敗:FAIL。錯誤僅會在服務請求中的第一個實例時打印一次。
步驟 3 — 座標
在規劃座標之前,閱讀 references/geometry.md。
簡短版本:一個 COORDINATES 物件,從左到右,從上到下佈局。每個節點:{ top: px, centerX: px }。群組使用相同的物件的 groups 鍵。邊是一個邊陣列:{ from: "name", to: "name", label: "label", kind: "primary" | "secondary" | "dev" }。對於 Amazon VPC 內的邊:{ from: "name", to: "name", label: "label", kind: "primary" | "dev" }(在 VPC 內部,secondary 不等同 aws;它是一條 primary aws 邊)。
在生成構建腳本之前務必閱讀 references/geometry.md。
步驟 4 — 建置
python3 scripts/build.py <icons-dir> <coordinates-file.json>
python3 <icons-dir>/build.py <icons-dir> <coordinates-file.json>
第一種形式使用此技能包捆綁的 build.py。第二種形式使用腳本先前放置在那裡的 build.py(無操作差異;捆綁的腳本僅是為了與 pack 佈局保持一致而設置)。
成品: 中的 out.{html,png,tsx}。
步驟 5 — 渲染
在傳遞前,務必先渲染 PNG 並檢查。 switch_to_tab 和視覺檢查是確認所有預期內容都已正確渲染的唯一可靠方法。vision_analyze 會看到解析度太低以至於無法使用的影像,除了給出粗略的形狀外……但仍然比什麼都沒有好。
python3 scripts/render_png.py <icons-dir>
注意: 如果最終成品僅是 PNG,請將 HTML 保留在 <icons-dir> 中:不要刪除您的真相來源。
步驟 6 — 傳遞
將 out.html 作為真相來源傳遞(使用 MEDIA:/absolute/path/to/out.html),以及詢問的格式(使用 MEDIA:/absolute/path/to/out.png)。將深色 PNG 額外存為 out-dark.png 並作為 MEDIA:/absolute/path/to/out-dark.png 傳遞。
MEDIA:/absolute/path/to/out.html
MEDIA:/absolute/path/to/out.png
MEDIA:/absolute/path/to/out-dark.png
使用 vision_analyze 檢查淺色和深色 PNG。
如果要求的是 TSX,請在將其作為 MEDIA:/absolute/path/to/out.tsx 傳遞前,使用 write_file 編寫它。
步驟 7 — 分享
如果要求,手動呼叫 share.py:
python3 scripts/share.py <icons-dir>
這會建立一個 zip 檔案並將其儲存到圖示目錄;壓縮內容與 HTML / PNG 相同。
版本
1.0.0
初始發布。