stack-diagram について
技術やサービスの一覧から、エンジニアリング図面風のアーキテクチャ図を作るスキルです。公式アイコン、グループ化した要素、ラベル付き接続を含む単体 HTML を元に、PNG や TSX などを生成します。
主な機能
- 01ノードとフローから図を作成
- 02公式ロゴとアイコンの取得
- 03関連コンポーネントのグループ化
- 04単体で動作する HTML の生成
- 05PNG のレンダリングと TSX の派生
活用シーン
- 01サービスアーキテクチャの可視化
- 02デプロイ先と実行環境のグループ表示
- 03主要・副次データフローの記録
- 04図を PNG または TSX に書き出し
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ caru-ini/ stack-diagram --skill stack-diagramインストール後、Claude Code で/stack-diagramを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEassets/template.htmlassets/fonts/OFL-Geist.txtOFL-JetBrainsMono.txtREADME.mdassets/generic/browser.svgdevice.svginternet.svgserver.svguser.svgreferences/geometry.mdtsx.mdscripts/build.pyfetch_icons.pyrender_png.py詳細
stack-diagram
白いタイル上に実際のロゴを配置し、ラベル付きのグループボックス(クラウドベンダーの VPC 図のようなもの)、等幅フォントのラベル付き直交矢印、涼しげなグラフ用紙風の背景を備えた、エンジニアリング図面スタイルのアーキテクチャ図を作成します。単独で完結する HTML ファイルを唯一の正とし、PNG/TSX/成果物はそこから生成します。
要件
- Python 3.9 以降(
fetch_icons.pyとbuild.pyは標準ライブラリのみ) - アイコンの取得にはアイコンソース(svgl.app、raw.githubusercontent.com、cdn.jsdelivr.net、さらに
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 — 内容
ユーザーが指定した技術/サービスの一覧をもとに、次のように決めます。
- ノード:各技術を 1 つのノードにします(名前+
http server、sqlite dbのような短い小文字の役割名)。 - グループ:同じランタイム、ベンダー、リポジトリを共有するものをボックスで囲みます(例:ランタイムボックスを内包するクラウドプロバイダーのボックス、ツール群をまとめるモノレポのボックス)。1 階層のネストは問題ありませんが、それ以上は見づらくなります。グループラベルはブランド独自の大文字・小文字の表記(
GitHub、npmなど)を使います。テンプレートにはその表記のまま表示されます。 - エッジ:次の 3 種類があります。
- アクセントカラーの実線=主要なリクエスト/データフロー(一続きの経路にすると見やすくなります)
- ニュートラルカラーの実線=副次的な内部接続
- ニュートラルカラーの破線=開発時/デプロイ時の関係(CI、git フック、IaC デプロイ)
ユーザーがツールの一覧だけを提示した場合は、各ツールの性質から妥当なグループとフローを推測します。ツールが曖昧で、どちらに解釈しても図が誤ったものになり得る場合に限り、質問してください。
ステップ 2 — アイコン
python3 scripts/fetch_icons.py <icons-dir> tanstack hono drizzle "betterauth:better-auth" "orpc=https://orpc.unnoq.com/logo.webp"
指定形式:name(スラッグとして使用する名前)、name:slug(異なるスラッグ)、name=URL(明示的な URL)。スクリプトは svgl → devicon → gilbarbara/logos の順に試し、ファイルと manifest.json を書き込み、塗りが白のアイコンにフラグを付けます。svgl(svgl.app)には、最新の公式マーク(TanStack、Better Auth、Hono など)がそろっているため、最初に使います。ロゴにライト版とダーク版がある場合、ライト版を <name> とし(どちらのテーマでもタイルは白です)、ダーク版はグループラベル用に <name>_dark として保存します。svgl はタイトルの完全一致でのみ照合するため、見つからなければそのまま次に進みます。また、その API では wordmark バリエーションも提供されています。横長のグループラベルには役立つこともありますが、タイルには使いません。
仕組みよりも重要なルール:
- ロゴの色は絶対に変更しないでください。 ユーザーは気づきます。ロゴが白い、または白いタイルでは薄すぎる場合、塗りを変更せず、暗いタイル(
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です)。 - 抽象的な概念には、テキストではなくピクトグラムを使ってください。 「dev environment」、「cron」、「queue」、「cache」、「webhook receiver」などのノードにはブランドがありません。
name:lucide/<icon>で Lucide の線画アイコンを使ってください(例:devenv:lucide/terminal、cron:lucide/clock。lucide.dev/icons を参照してください)。タイル内にテキストを入れたり、絵文字を使ったりしないでください。 - ベンダーのサブ製品(Cloudflare D1/R2/KV、AWS の無数のサービスなど)には、通常、個別のロゴがありません。タイルにはベンダーのロゴをそのまま使い、ノード名で違いを示してください(「Cloudflare D1」/「sqlite db」)。
- ブランドではないノード(ユーザー、ブラウザー、インターネット、デバイス、ベアメタルサーバー)には、
assets/generic/からグリフをアイコンディレクトリにコピーしてノード名で保存するか、name:lucide/<icon>を使ってください。絵文字は使わないでください。これらはブランドロゴではないため、図のインク色に合わせて色を付けてもかまいません(フェッチスクリプトが Lucide のアイコンには自動で色を付けます)。 - グループラベルのアイコンは 14px で描画されるため、正方形のグリフマークが必要です。ワードマークや横長のロックアップは、このサイズでは潰れて見えます。メインのアイコンがワードマークの場合は、ラベル用にブランドの正方形アイコンを別途取得してください(通常、svgl にあります。それ以外の場合は、プロジェクト独自のアイコンまたはファビコンファイルを使います)。
- グループラベルは白いタイルではなく、グループの色合いの上に配置されるため、ダークテーマでは黒い部分のあるマークが見えなくなります。
fetch_icons.pyが<name>_darkを保存している場合は、ラベルにテンプレートのlt/dkペアを使ってください。ダーク版がなく、マークに黒い部分がある場合は、ラベルの<img>にplateクラスを追加してください(ダークテーマのみ白い背景が付きます)。 - ラスター形式のロゴ(png/webp)も使えます。ビルドスクリプトがすべてをデータ URI として埋め込むため、表示時に読み込む必要はありません。
ステップ 3 — レイアウト
座標系、間隔の定数、そして何よりも矢印がラベルのテキストを通過しないようにするエッジのアンカー規則については、references/geometry.md を読んでください。要約すると、ノードはタイルとその下のテキストで構成されます。垂直方向の矢印はタイル間ではなく、ノードボックスの境界をつなぎます。
ステップ 4 — ビルド
assets/template.html をコピーし、サンプルの GROUPS / EDGES / NODES / header セクションを独自の内容に置き換えてから、アセットをインライン化します(テンプレートのマークアップはフォーマットの説明も兼ねています)。<html> の lang を図のラベルの言語に設定します(デフォルトは en です。ブラウザーで日本語の字形バリエーションが選ばれるよう、日本語の場合は ja を使用します)。テンプレートには次の 2 つのオプションがあらかじめ用意されています。ダークバリアント(<html> に data-theme="dark" を設定します。ロゴが見えるようタイルは白のままです。グループラベルのアイコンはステップ 2 のルールに従い、矢印の先端と凡例のスウォッチはトークンに従って自動的に変わります)、および X がノードではなくグループである「プラットフォーム X にデプロイ」エッジです。矢印はグループ内で最も代表的なノードに向け、エッジにラベル(deploy)を付けると、正しく読み取れます。
python3 scripts/build.py my-diagram.html <icons-dir> out.html --fonts <skill>/assets/fonts
マークアップではアイコンを %%ICON_<name>%%、フォントを %%FONT_DISPLAY%%(Geist)/%%FONT_JBM%%(JetBrains Mono)として参照します。未解決のトークンがあると、ビルドは明確なエラーを出して失敗します。すべての色とフォントは、テンプレートにすでにある CSS カスタムプロパティを通して管理してください。値が散在している箇所を変更するのではなく、トークンを調整します。
ステップ 5 — 実際に見て確認する
レンダリングし、画像を実際に確認します。
python3 scripts/render_png.py out.html check.png --selector .canvas --scale 2
図に日本語のテキストが含まれる場合、レンダリング環境に日本語フォントが必要です。そうでないと、CJK 文字が気付かれないまま中国語の字形バリエーションで表示されます(ユーザーはすぐに気付きます)。スクリプトは警告を出して修正方法を表示します。テンプレートのフォントスタックには、すでに Noto JP のフォントが指定されています。
確認時のチェックリスト:
- 矢印がラベルのテキストと交差していない。矢印の先端がテキスト内に入っていない
- エッジラベルが読みやすい(紙の色の縁取りがあります。正しく機能していることを確認してください)
- ダーク表示のグループラベルのアイコンも含め、すべてのアイコンが見える(白地に白はよくある失敗です → 暗いタイルにします)
- グループラベルが各グループの左上に配置され、ノードやエッジと重なっていない。各グループの左右の余白が揃っている
- グループの枠からはみ出しているものがない。キャンバスの端で切れているものがない
問題がなくなるまで修正して再レンダリングします。この反復は手軽です。テキストが重なった図を公開してはいけません。
ステップ 6 — 納品する
- HTML(デフォルト):ビルドしたファイルそのものです。自己完結しており、オフラインで動作します。
- PNG:必ず、ビルド済み HTML をヘッドレス Chromium でスクリーンショットして生成します(
render_png.py。テキストを鮮明にするには--scale 2を指定します)。matplotlib/PIL/スタンドアロンの SVG ラスター化ツールで別の画像を描画してはいけません。HTML が唯一の信頼できる情報源であり、ブラウザーによるテキスト/SVG のレンダリングによって正しく表示されます。デフォルトでは、スクリプトは角を直角にして(スクリーンショット時のみ角丸を取り除きます)両方のテーマを出力します(out.pngはライト、out-dark.pngはダーク)。ユーザーが一方のみを指定した場合を除き、両方を納品してください。--singleは作成時のままのドキュメントをキャプチャします。図だけを対象にする場合は.canvasを指定し、ページ全体を対象にする場合は--full-pageを指定します。 - TSX:
references/tsx.mdに従って変換します(依存関係のない、自己完結型の React コンポーネントです)。 - アーティファクト(環境にアーティファクト作成ツールまたはページ公開ツールがある場合):環境のアーティファクトツールでビルド済み HTML を公開します。すべてデータ URI としてすでにインライン化されているため、アーティファクトのネットワーク遮断サンドボックスは問題になりません。会話の中でユーザーが図を繰り返し編集する場合はこの方法を優先し、ほかの場所に貼り付ける必要がある場合は PNG も併せて提供します。
複数の形式が必要な場合は、HTML を一度ビルドし、そこからほかの形式を作成します。
フッターには、実際に使用したアイコンの出典を記載します。出典は icons ディレクトリの manifest.json にある各エントリの source フィールドです(例:icons: svgl / devicon / Lucide)。ブランドロゴは引き続き各所有者の商標です。ユーザーから削除の依頼がない限り、クレジットの後にテンプレートの「made with stack-diagram」リンクを残します。デフォルトの PNG はキャンバスのみをキャプチャするため、このリンクは PNG には含まれません。