figure について
Figureは、JSONで図を定義し、アニメーションSVGとして出力するツールです。ドキュメントやPR向けの説明図を作成でき、図のデータをSVGに埋め込むため、後から読み込んで編集できます。
主な機能
- 01JSONで図を作成
- 02標準入力からアニメーションSVGを出力
- 03シーン、ビート、矢印を表現
- 04編集可能な図のデータをSVGに埋め込み
- 05静止画やダークテーマのSVGを出力
活用シーン
- 01PRの説明でフローを図示
- 02READMEにアニメーション図を追加
- 03ブログ記事用の図を作成
- 04既存のSVG図を編集
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ vectorize-io/ hindsight --skill figureインストール後、Claude Code で/figureを入力して読み込まれたか確認します。
詳細
図
アニメーション SVG は 1 つだけで、スクリプトもアップロードも不要です。Markdown を表示できる場所ならどこでもレンダリングされ、再生されます。GitHub の README、PR や issue のコメント、ブログ記事、Notion などです。どのサイズでも鮮明で、閲覧者の ライトテーマまたはダークテーマに合わせて表示されます。
図はGiottoの図です。1 つの JSON ドキュメントで、ドキュメントサイトのインタラクティブな図で使われているものと同じ
形式です(hindsight-docs/figures/*.json)。
作成するのは図の JSON で、SVG ではありません。 コマンド 1 つでレンダリングできます。ビルドもブラウザーも不要です。
1. 図を作成する
リポジトリ内にファイルとして保存しないでください。 これは入力であり、成果物ではありません。手順 2 のようにパイプで渡せば、 レンダリングされた SVG に元データのコピーが保存されます。
{
"title": "Retain",
"speed": 2000,
"elements": [
{ "id": "root", "type": "group", "children": ["agent", "api", "bank"], "layout": { "direction": "row", "gap": 48 } },
{ "id": "agent", "type": "rectangle", "content": [{ "type": "title", "text": "Your AI Agent" }] },
{ "id": "api", "type": "group", "label": { "title": "Hindsight API" }, "children": ["retain"], "layout": { "direction": "column", "gap": 24 } },
{ "id": "retain", "type": "rectangle", "content": [{ "type": "title", "text": "Retain" }, { "type": "subtitle", "text": "LLM extraction" }] },
{ "id": "bank", "type": "group", "label": { "title": "Memory Bank" }, "children": ["facts", "obs"], "layout": { "direction": "column", "gap": 28 } },
{ "id": "facts", "type": "cylinder", "content": [{ "type": "title", "text": "Facts" }, { "type": "subtitle", "text": "world · experience" }] },
{ "id": "obs", "type": "cylinder", "content": [{ "type": "title", "text": "Observations" }] },
{ "id": "call", "type": "arrow", "route": "curved", "start": { "id": "agent" }, "end": { "id": "retain" }, "label": { "text": "retain()" } },
{ "id": "store", "type": "arrow", "route": "curved", "start": { "id": "retain" }, "end": { "id": "facts" }, "label": { "text": "extract" } },
{ "id": "consolidate", "type": "arrow", "route": "curved", "start": { "id": "facts" }, "end": { "id": "obs" }, "label": { "text": "consolidate" }, "quiet": true }
],
"scenes": [
{
"label": "retain()",
"beats": [
{ "edges": { "edge": "call", "data": "“Alice joined Google in March”" }, "say": "Your agent sends what happened." },
{
"edges": "store",
"show": { "facts": [{ "tag": "world", "tone": "blue", "text": "Alice joined Google", "meta": "Mar 2026", "mark": "new" }] },
"say": "An LLM pulls out the facts."
},
{
"edges": "consolidate",
"ms": 2600,
"show": { "obs": [{ "text": "Alice works at Google", "meta": "2 sources" }] },
"say": "The worker merges them into one belief."
}
]
}
]
}
要素 — フラットなリストです。group は children に ID を指定して配置します
(layout: { direction: "row" | "column", gap, align })。label: { title } はその周囲に枠を描画します。子要素は、レイアウトで指定しない限り上端または左端に揃います。ドキュメントの図のように、行では
align: "center"、列では(幅を揃えたボックスにするため)align: "stretch" を使ってください。rectangle のボックスは動作を担い、cylinder は静止したデータ、diamond は
判断を表します。ボックスの content はブロックで構成されます。title、subtitle、text、list、chips、code です。
すべての要素に安定した id を付けてください。
矢印 — { type: "arrow", start: { id }, end: { id }, label?: { text }, route: "curved", around?, quiet? }。
端点にはボックス またはグループ を指定します。around: "above" | "below" は間にあるボックスの上または下を通る弧を描きます。
quiet: true を指定すると、その矢印を使うシーンでのみ矢印が描画されます(横切る長い矢印に適しています)。
シーンとビート — 各シーンは図が伝える 1 つのストーリーで、SVG はそれらをループ再生します。ビートは 1 つの瞬間を表します。edges(矢印 ID、逆方向の移動またはデータチップを表す { edge, back, data }、または複数を同時に実行する配列)、say(キャプション)、show(シーンが終わるまでボックス内にカードを表示)、light(そのビートでボックスをハイライト。シーンに指定するとシーン全体に適用)、ms(ビートの継続時間)を指定します。
カードの行 — { tag?, tone?, text, meta?, mark?, mono? }。tone は blue | purple | green | orange | red | gray です。対象の種類(world、user、page など)には tag、詳細には meta、対象に起きたこと(new、✓、cited、↻)には mark を使います。どのテキストでも **bold** と `code` が使えます。
フォーマット全体は node_modules/giotto/lib/edit.js の FORMAT テキストにあります。hindsight-docs/figures/ にある 13 個の図は動作する例です。最も手早く始めるには、最も近い例をコピーしてください。
内容は正確かつ具体的にしてください。プレースホルダーより実際のサンプルデータを使い、ラベル、カード、キャプション内の主張はすべて実際のコードの動作と一致させてください。推測せず、コードを確認してください。
2. レンダリングする — stdin から渡して、ディスクに何も残さない
npx giotto export - path/to/out.svg <<'DOC'
{ "title": …, "elements": […], "scenes": […] }
DOC
giotto はドキュメントサイトの依存関係(リポジトリのルートで npm install)から利用できます。引用符で囲んだ
<<'DOC' ヒアドキュメントは JSON を変更せずに渡し、生成されるファイルは SVG だけです。レイアウトとシーンの警告は stderr に出力されるため、修正してください。存在しない要素への参照(矢印の端点、グループの子要素、シーンで塗りつぶすボックス)はエラーとなり、エクスポートは失敗して何も書き出されません。
そのほかの形式:
npx giotto export hindsight-docs/figures/retain.json out.svg # a docs figure, as an SVG
npx giotto export doc.json out.svg --theme dark --static # one still frame, dark
npx giotto spec out.svg # print the diagram an SVG carries
すべての SVG は図を <metadata id="giotto-doc"> に埋め込むため、JSON を保管していなくても後から編集できます。giotto spec で読み戻し、必要な箇所を変更して再度レンダリングしてください。
3. 出荷前に図を確認する
必ず確認してください。ボックスからはみ出すテキスト、ボックスを横切る矢印、動きと一致しないキャプションは、見ればすぐわかりますが、ソースだけではわかりません。
cd $(dirname out.svg) && python3 -m http.server 8777 & # the browser tool blocks file:// URLs
次に http://localhost:8777/out.svg を開いてスクリーンショットを撮り、数秒待ってからもう一度撮影し、後のビートも確認してください。人が確認する場合は open out.svg でも開けます。
4. 適切な場所に配置する
-
PR または issue のコメント — ブランチに SVG をコミットし、raw URL を参照します:
。GitHub はすぐにレンダリングし、アニメーションを再生します。 -
README またはリポジトリのドキュメント — コミットして、相対パスでリンクします。
-
ブログ記事 —
hindsight-docs/static/img/blog/に保存し、/img/blog/<name>.svgとして参照します。 -
ドキュメントサイト自体のページ — SVG は使わないでください。これらのページでは、タブ、一時停止、速度調整、ホバーに対応したインタラクティブプレーヤーを使います。図を
hindsight-docs/figures/<name>.jsonとして保存し、ページに追加します:import Figure from '@site/src/components/Figure'; import retain from '@site/figures/retain.json'; <Figure doc={retain} />
SVG でできないこと
コントロールはなく、すべてのシーンをループ再生します。タブ、一時停止、ホバーには対応していません。これらが必要な図は、ドキュメントサイトに配置します。ループがすぐに一周するよう、SVG は 1 つか 2 つのシーンに収めてください。