mcpField
Z
Zenith

Zenith

ローカル
github.comメディア・デザイン222 週間前に更新

Zenith について

Zenith は AI エージェント向けのデザインドキュメント形式およびエンジンで、デザインをプレーンテキストの .zen ファイルとして保存します。同じファイルからは常に同じピクセルがレンダリングされ、PNG、SVG、PDF で出力できます。コマンドラインツールと npm パッケージの MCP サーバーを提供します。

主な機能

  1. 01KDL ベースのプレーンテキスト .zen 形式
  2. 02検証診断、フォーマット、デザイントークンの一覧表示
  3. 03PNG、SVG、PDF への決定的なレンダリング
  4. 04型付きトランザクションによる安全な編集とプレビュー
  5. 05コマンドラインツールと Rust ライブラリ crate

活用シーン

  1. 01エージェントによるポスターや図版の生成と検証
  2. 02バージョン管理上でのテキスト差分によるデザイン変更のレビュー
  3. 03複数ページの文書やデザインバリエーションの一括レンダリング

MCP 対応

本プロジェクトは npm で公開されている @zenitheditor/zenith-mcp パッケージを提供し、zenith エンジンの機能を MCP クライアントに公開する MCP サーバーとして動作します。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"zenitheditor-zenith": {
"command": "npx",
"args": [
"-y",
"@zenitheditor/zenith-mcp"
]
}
}
}
起動コマンドnpx -y @zenitheditor/zenith-mcp

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npm@zenitheditor/zenith-mcp0.0.8

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

Zenith

Zenith — AI エージェントに実際のデザインを作成・編集する力を与えます
AI エージェントの時代に向けて構築された、デザインドキュメント形式とエンジンです。

読み取り、差分確認、レビュー、検証ができ、エージェントが安全に編集できるプレーンテキストの.zenデザインファイルです。決定論的にコンパイルされ、ピクセル単位で正確な PNG、自己完結型 SVG、印刷対応 PDF を生成します。

インストール クイックスタート 機能 検証 コマンド エージェント

CI の状態 GitHub の最新リリース crates.io の zenith-tool crates.io のダウンロード数 MCP レジストリへの掲載 Zenith のショーケース例 ライセンス

この README にあるすべてのバナーと図は、Zenith で作成されています。ソースはassets/showcase/にあります。


Zenith は、ポスター、スライド資料、書籍、ソーシャルメディア用グラフィック、図などを作成するための、デザインファイル向けプレーンテキスト形式とエンジンです。考え方はシンプルです。デザインはコードと同じように扱えるべきです。 読み取り、差分確認、レビュー、テストができ、エージェントが安全に編集できる必要があります。

.zen ファイルは、人間が読み取れる KDL テキストです。エンジンはこれを解析し、多数の診断項目に照らして検証してから、バックエンドに依存しないシーンにコンパイルします。そして、同じファイルを毎回まったく同じピクセルで、PNG、自己完結型 SVG、または印刷対応 PDF としてレンダリングします。

このページをざっと読みやすくするため、以下のセクションは折りたたまれています。各見出しの ▸ をクリックすると展開できます。インストールとクイックスタートは、デフォルトで展開されています。

インストール

zenith CLI のインストールには、インストールスクリプトの使用をおすすめします。スクリプトがプラットフォームを検出し、GitHub Releases から対応するビルド済みバイナリをダウンロードします。

Linux / macOS

curl -fsSL https://raw.githubusercontent.com/zenitheditor/zenith/main/scripts/install.sh | sh

Windows(PowerShell)

irm https://raw.githubusercontent.com/zenitheditor/zenith/main/scripts/install.ps1 | iex

インストール先を変更するには ZENITH_INSTALL_DIR を設定します(デフォルトは ~/.local/bin です)。

ZENITH_INSTALL_DIR=/usr/local/bin \
  curl -fsSL https://raw.githubusercontent.com/zenitheditor/zenith/main/scripts/install.sh | sh
cargo を使用する場合
cargo install zenith-tool    # from crates.io (installs the `zenith` binary)
cargo install --git https://github.com/zenitheditor/zenith zenith-tool   # from source

エンジンを直接利用する Rust プロジェクト向けに、13 個のライブラリクレートがそれぞれ独自の名前で公開されています。zenith-geometry、zenith-session、zenith-core、zenith-layout、zenith-raster、zenith-scene、zenith-perception、zenith-zpx、zenith-render、zenith-tx、zenith-producers、zenith-pipeline、および zenith-editor です。zenith-editor-wasm と zenith-editor-bench は公開されていません。

npm を使用する場合
npm install -g @zenitheditor/zenith-mcp
npx -y @zenitheditor/zenith-mcp --help

npm パッケージは、GitHub Releases から対応するビルド済みの zenith バイナリをインストールします。MCP Registry のローンチ経路を主な用途としています。スコープなしの zenith バイナリは、引き続き Rust CLI です。

GitHub リリース

GitHub Releases から直接ダウンロードしてください。

プラットフォームアーキテクチャアセット
Linuxx86_64zenith-<version>-linux-x64.tar.gz
Linuxaarch64zenith-<version>-linux-arm64.tar.gz
macOSx86_64zenith-<version>-macos-x64.tar.gz
macOSApple Siliconzenith-<version>-macos-arm64.tar.gz
Windowsx86_64zenith-<version>-windows-x64.zip
更新
zenith update                   # latest stable release
zenith update --pre             # latest prerelease
zenith update --version <tag>   # a specific release tag, e.g. the ones on the Releases page

zenith --version で確認してください。

ソースからビルド

ローカル開発またはソースからインストールする場合:

git clone --recurse-submodules https://github.com/zenitheditor/zenith
cd zenith
cargo build --release
cargo install --path zenith-cli   # installs `zenith` to ~/.cargo/bin
./scripts/install.sh --local      # installs the local build to ~/.local/bin

リリースバイナリは target/release/zenith に生成されます。C ツールチェーンやシステムライブラリは不要です。依存関係グラフに C は含まれず、ワークスペース全体で unsafe は禁止されています。

クイックスタート

zenith validate examples/hello.zen          # report diagnostics (add --json for machine output)
zenith fmt examples/hello.zen               # canonical, idempotent formatting
zenith fix draft.zen --apply                # apply machine fixes (tokens, typos) in one step
zenith tokens examples/hello.zen            # list design tokens and their resolved values
zenith inspect examples/hello.zen           # print the node tree (read-only)
zenith render examples/hello.zen --png hello.png          # render to PNG

zenith render examples/multipage.zen --all-pages out/     # one PNG per page
zenith render examples/hello.zen --pdf hello.pdf          # print-ready PDF
zenith render examples/hello.zen --svg hello.svg          # self-contained SVG
zenith render examples/multipage.zen --svg page.svg --page 2
zenith render examples/multipage.zen --all-pages-svg svg-pages/
zenith render examples/hello.zen --scene scene.json       # dump the scene IR
エクスポートフラグ出力
--svg OUTデフォルトでは 1 ページ目を出力し、テキストはアウトライン化されます。
--pdf OUTデフォルトではすべてのページを 1 つの PDF に出力します。
--page NPDF を含む、単一出力フラグで出力するページを 1 つ選択します。
--all-pages-svg DIRドキュメントの順序で page-N.svg を出力します。
--raster-scale FSVG/PDF のフォールバック解像度です。有効な範囲は有限値の 0 < F <= 4、デフォルトは 1 です。
--scale FPNG の出力倍率です。有効な範囲は有限値の 0 < F <= 4、デフォルトは 1 です。
--deny render.svg_rasterizedラスターフォールバックが必要な SVG エクスポートをブロックします。
--deny render.pdf_rasterizedラスターフォールバックが必要な PDF エクスポートをブロックします。
  • SVG アセット: RGB カラーと埋め込み画像アセットにより、生成物は自己完結します。
  • SVG テキスト: アウトライン化すると外観は保持されますが、編集、選択、検索はできなくなります。
  • SVG フォールバック: エフェクトは適用範囲全体をキャプチャします。通常以外のブレンドではページ全体をキャプチャします。範囲をまたぐ場合やビットマップグリフではキャプチャが必要です。
  • PDF フォールバック: サポートされていない機能は、必要な範囲またはページ全体をキャプチャします。キャプチャされたテキストは選択や検索ができなくなります。キャプチャされたリンクはクリック先が失われます。
  • 解像度: --raster-scale は、ベクターの形状やページ寸法を変えずにフォールバックのピクセル数を変更します。既存のビットマップアセットは元の解像度を維持します。
  • レポート: render.svg_rasterized と render.pdf_rasterized は、ページ、コマンド範囲、理由を報告します。JSON にはラスタライズされた領域が構造化データとして含まれます。
  • PDF エラー: CLI と MCP は、キャプチャエラーとリソースエラーを拒否します。Vec<u8> を返す従来のライブラリ API は、互換性のため出力を継続します。厳密なエラー処理にはレポート API を使用してください。
  • ポリシー: 診断によってブロックされた場合、出力は書き込まれません。ソースの検証後にエクスポートレポートを確認してください。
  • 書き込み: 各ファイルは同じディレクトリ内の一時ファイルを経由してリネームされます。書き込みエラーが発生しても既存の出力先は保持されます。後続の I/O エラーが発生した場合、それ以前に確定した出力は残ることがあります。
  • バッチレポート: 部分的な行やバリアントでは、失敗ステータスでも確定済みのパスが保持されます。マニフェストの書き込みエラーが発生しても、バッチのエラー数は保持されます。
  • ファイルシステムの制限: 読み取り専用の出力先への書き込みは拒否されます。シンボリックリンクを出力先に指定すると、解決先のターゲットが置き換えられ、リンクは維持されます。置き換え後も権限は維持され、ほかのハードリンクは変更されません。クラッシュ時の耐久性は保証されません。
zenith render examples/multipage.zen --pdf book.pdf --raster-scale 2 --json
zenith render examples/hello.zen --svg hello.svg --raster-scale 2 --json

最小の有効なドキュメント:

zenith version=1 {
  project id="proj.hello" name="Hello Zenith"
  tokens format="zenith-token-v1" {
    token id="color.bg" type="color" value="#f8fafc"
    token id="color.ink" type="color" value="#111827"
    token id="font.body" type="fontFamily" value="Noto Sans"
    token id="size.heading" type="dimension" value=(px)42
  }
  styles {}
  document id="doc.hello" title="Hello Zenith" {
    page id="page.hello" w=(px)480 h=(px)160 {
      rect id="rect.bg" x=(px)0 y=(px)0 w=(px)480 h=(px)160 fill=(token)"color.bg"
      text id="text.hello" x=(px)24 y=(px)24 w=(px)432 h=(px)112 fill=(token)"color.ink" font-family=(token)"font.body" font-size=(token)"size.heading" { span "Hello Zenith" }
    }
  }
}

図形、リッチテキスト、外部ファイルから読み込むインライン markdown、コードブロック、画像、フレーム/グループ、複数ページのドキュメントやスタイルに加え、より高度な機能である gradient、shadow、blur、filter、mask、table、flowchart(図形+コネクター)、グラフ(棒/折れ線/面/円/ドーナツ/スパークライン。凡例、値ラベル、データバインディングに対応)、anchors を扱う、実行可能な .zen ファイルについては examples/ を参照してください。

理由

コードにはソース管理、型、テスト、PR がありました。デザインファイルにはそのどれもなく、それが人々を悩ませ、AI の妨げになっています。

コードにはソース管理、型、テスト、プルリクエストがありました。デザインファイルにはそのどれもありません。デザインファイルは不透明な塊で、差分を確認できず、変更をレビューできず、同じファイルでもマシンによって表示が異なることがあります。

これは人々にとって問題であり、AI にとってはさらに大きな問題です。エージェントがすでにコードを書いてプルリクエストを作成できるのは、コードが読み取って推論できるテキストだからです。デザインツールに入ると、エージェントは何も見えなくなります。エージェントに「見出しをブランドカラーの赤にして、レイアウトを詰めて」と頼んでも、安全に変更できる対象がありません。安定したターゲットも、検証も、プレビューも、結果を確認する方法もないのです。

Zenith はこの問題を解決します。目標は、デザインファイルをコードと同じように安全に自動化できるようにすることです。

  • プレーンテキストを自分で所有できます。読みやすく、差分を確認でき、いつまでも自分のものです。
  • 安定した IDにより、すべての変更がマウスドラッグではなく、レビュー可能なパッチになります。
  • 決定論的なレンダリングにより、同じファイルから常に同じピクセルが生成されます。
  • 実用的な検証により、テキストが収まり、色がデザインシステムに準拠し、何もページからはみ出さないことを確認できます。
  • 安全な編集では、すべての変更が型付きトランザクションとなり、反映前に検査とプレビューが行われ、ソースの差分と監査記録も残ります。

AI 画像生成ではありません

画像モデルとは正反対です。Zenith が生成するのは平坦な画像ではなく、編集可能なデザインです。

よくある誤解なので、はっきりさせておきます。Zenith は Nano Banana、ChatGPT image、Grok Imagine のような画像モデルとは正反対です。

画像生成ツールが出力するのは平坦な画像です。ピクセルの集まりなので、開いてロゴを動かすことはできず、見出しを正確なブランドカラーにすることもできません。また、「同じものを別の日付で」と頼むと、異なる画像が生成されます。編集、レビュー、保証の対象となるものはありません。

Zenith が生成するのは画像ではありません。生成するのは、_デザインそのもの_です。すべての要素が実体を持ち、指定できる、構造化された編集可能なドキュメントです。エージェント(または人)は、1 行を変更したり、カラーのトークンを置き換えたり、ブランドに沿ったバリエーションを 100 種類再生成したりできます。そして、レンダリングの結果はすべて正確で、再現可能です。AI がソースを書き、編集し、Zenith がその意味と見た目を保証します。

API を後付けしたツールではなく、エージェントネイティブを最優先

基盤となるのは、プログラムから操作できる決定論的なエンジンです。ビジュアルエディターはその上にあるクライアントであり、自動化が入り口です。

多くのデザインツールは、人がボックスをドラッグすることを前提に作られており、自動化 API は後から付け足された後付けの機能にすぎません。ソフトウェアによる操作を想定していないモデルの上に、薄く機能が限られたレイヤーを重ねています。

Zenith は逆の発想で作られています。基盤となるのは、プログラムから操作できるテキストベースの決定論的なエンジンです。エージェント、スクリプト、コマンドラインから直接操作します。つまり、自動化は裏口ではなく、正面玄関なのです。

エディター。 エンジンと CLI は、AI エージェントが操作するインターフェースです。ブラウザーエディターは同じエンジン上のクライアントです。デザイナーがボックスを少し調整し、エージェントが 100 種類のバリエーションのスタイルを変更する場合も、どちらも同じ決定論的なコアを使い、同じ検証、トランザクション、バージョン履歴を利用します。GUI は、自動化を後付けした別製品ではありません。

## 仕組み
1 つの決定論的なパイプライン:解析 + 検証 → AST → コンパイル → シーン IR → レンダリング(PNG/SVG/PDF)。

.zen ドキュメントは、単一の決定論的なパイプラインを通ります。各ステージは、明確な契約境界を持つ独立したクレートです。そのため、GPU バックエンドもエディターも、同じシーン IR を利用できます。

パイプライン:.zen ソース → 検証 → コンパイル → シーン IR → レンダリング

Zenith によるレンダリング — ソース:assets/showcase/pipeline.zen。

  design.zen  (KDL plain text)
       │  parse + validate           zenith-core   →  diagnostics (Error/Warning/Advisory)
       ▼
  Document AST  ──transaction ops──▶  Document AST'  zenith-tx  →  dry-run / apply + audit record
       │  compile                    zenith-scene + zenith-layout
       │    · resolve tokens, geometry, anchors
       │    · shape text (rustybuzz), wrap, hyphenate
       ▼
  Scene IR  (backend-neutral display list)
       │  render                     zenith-render
       ├─▶ PNG   (tiny-skia, byte-identical)
       ├─▶ SVG   (outlined text, embedded assets)
       └─▶ PDF   (vector, native CMYK, bleed / trim / crop)

  local history / undo / versions    zenith-session   (off the render path; never affects pixels)

レンダリングパスに関わるすべての処理は、決定論的で C に依存しません。時間、乱数、HashMap、unsafe、C への依存はありません。どのマシンでも、同じバイト列を入力すれば、常に同じバイト列が出力されます。

できること

トークン、充実したノードセット、本格的なタイポグラフィ、視覚効果、アンカー、レシピ、トランザクションエンジン、決定論的な PNG/SVG/PDF、履歴、ライブラリ、データマージ。 - **スキャフォールドと識別情報** — `zenith new` を実行すると、編集できる状態のドキュメントが作成されます(最小限の有効なテンプレート、または `--starter flyer|letterhead|handout|deck|poster|menu|card|report` で指定する、仕上げ済みでテーマを適用できるレイアウト。デフォルトの拡張子は `.zen` で、親ディレクトリも作成されます)。初回の書き込み時に安定した `doc-id` が発行されます。どの `.zen` ファイルも、最初の編集時に手動で設定しなくても、透過的に識別情報とワークスペースストアを取得します。 - **プレーンテキストの `.zen` 形式** — `project`/`tokens`/`styles`/`document`/`page` 構造を持つ KDL v2 ソースです。すべてのノードに安定した ID が付与されます。 - **デザイントークン** — `color`(sRGB **および**ネイティブ CMYK)、`dimension`、`number`、`fontFamily`、`fontWeight`、`gradient`(linear/radial)、`shadow`、`filter`、`mask` に対応し、エイリアスチェーンの処理と循環検出も行います。 - **豊富なノードセット** — `rect`、`ellipse`、`line`、`polygon`、`polyline`、`text`、`code`、`image`、`frame`、`group`、`pattern`、`shape`、`connector`、`chart`、`instance`、`field`、`footnote`、`toc`、`table` に対応し、前方互換性のため、未知のノードも損失なくそのまま保持します。 - **本格的なタイポグラフィ** — バンドルされた Noto Sans/Noto Sans Mono、フォントフォールバック、Knuth–Liang のハイフネーション、リッチなインラインスパン(太字/斜体/下線/取り消し線/ハイライト/インラインコード/リンク)、連結テキストのフロー、ドロップキャップ、タブリーダー、テキストの回り込みに対応した `rustybuzz` のシェーピングを使用します。グリフを利用できない場合は `font.glyph_missing` 診断が表示されます。 - **長文テキストをすっきり管理** — 外部の `.md`/`.txt` ファイル(`text src="copy/article.md"`)またはデータフィールドから本文を読み込み、`.zen` を小さく保てます。**markdown**(`format="markdown"`)を指定すると、インライン装飾(`**bold**`、`*italic*`、`==highlight==`、`++underline++`、`~~strike~~`、`` `code` ``、`[label](url)`)と完全な**ブロック構造**(`# headings`(h1–h6)、空行区切りの段落、引用、番号付き/番号なしリスト、フェンス付きコードブロック、`---` の水平線)の両方を利用できます。役割ごとのタイポグラフィ(フォント、サイズ、ウェイト、塗り、間隔)は、ドキュメント、ページ、またはテキストのスコープにある `block role="h1" …` 宣言で制御します(カスケード順:text > page > doc)。これにより、`.zen` がすべてのレイアウトとスタイルを担い、`.md` ファイルは純粋な文章のまま保たれます。1つのボックスに収まらない長文コンテンツは、複数の `text` ノードを `chain` で連結して手動でページ分割できます。コンテンツが収まらない場合は `text.overflow` 警告が表示されます。 - **視覚効果** — 線形および放射状グラデーション、複数レイヤーのシャドウ、ガウスぼかし、フェザー付きマスク、12種類の Porter-Duff ブレンドモード、透明度のカスケード、角ごとの個別の角丸、画像のフィット/クリップ形状/オブジェクト位置に対応します。 - **アンカー** — ページ、安全領域、親コンテナ、または兄弟ノードを基準にした9点配置に対応します(優先順位:zone > sibling > parent > page)。すべて明示的で決定論的なジオメトリに変換されます(アンカーがなければ、手動配置した座標とバイト単位で同一になります)。 - **プロシージャルレシピ** — `recipes` の来歴ブロックに、生成モチーフの作成方法(種類、シード、ジェネレーター、パラメーター、パレットトークン、展開されたノード ID)を記録します。型付きレシピトランザクションを使って内容を確認・編集できるため、プロシージャルなビジュアルを再現可能かつ再調整可能な状態に保てます。 - **トランザクションエンジン** — 型付きの操作セット(塗り/線/ジオメトリの設定、追加/削除/親の変更/グループ化、整列/分布、ページ操作、トークン操作、検索と置換、パターンの分離など)を、デフォルトでは**ドライラン**として適用します。参照整合性と ID の一意性を保証し、ソース差分、移動/サイズ変更されたノードのボックス、影響を受けたノード ID、監査記録を提示します。 - **決定論的レンダリング** — tiny-skia によるピクセル単位で正確な PNG と、印刷対応の PDF(ネイティブ DeviceRGB/CMYK、MediaBox/TrimBox/BleedBox、埋め込みタイムスタンプなし)を出力します。単一ページ、全ページ、または見開きページに対応します。シーン IR は JSON にダンプできます。 - **画像ではなく、本物の PDF テキスト** — PDF 出力には、選択/検索/インデックス作成が可能な本物のテキスト(サブセット化フォント+ToUnicode)とクリック可能なハイパーリンクがデフォルトで埋め込まれます。`text`/`code` ノードに `selectable=#false` を設定すると、代わりにアウトラインとしてレンダリングされます。`--embed-full-fonts` を指定すると、サブセットの代わりにフォント全体を埋め込みます。不透明な線形および放射状グラデーションは、ネイティブのシェーディングを維持します。ビットマップグリフ、半透明のグラデーション、または外側/非厳密なストップオフセットを持つグラデーションは、それらを含むスコープ全体がラスタライズされます。グループの不透明度を必要とする効果やコンポジットレイヤーも、それらを含むスコープ全体がラスタライズされます。通常以外のブレンドでは、背景を維持するためページ全体がラスタライズされます。ラスタライズ範囲内のテキストとリンクは、選択およびクリックできなくなります。範囲外のテキストは、ネイティブの PDF の動作を維持します。対応する塗りと単色の線を持つインポート済み SVG パスは、ネイティブベクターを維持します。インポート済みの放射状グラデーション、グラデーションの線、パターン、クリップ、マスク、フィルター、ネストされた画像、未対応のペイント変換は、それらを含むスコープ全体がページのピクセル解像度でラスタライズされます。SVG のグループ不透明度と配置不透明度も同じフォールバックを使用します。 - **ローカル履歴** — ドキュメントごとの識別情報(ファイルに記録され、レンダラーでは無視される ULID の doc-id)、取り消し/やり直し用の一時的なセッション DAG、名前付きバージョンと復元に対応する永続的なコンテンツアドレス指定型バージョンストア(SHA-256+DEFLATE)を備えています。すべてレンダリング経路とは切り離されています。 - **ワークスペースのスクラッチ候補** — 履歴と同じ場所に、コンテンツアドレス指定型の `.zen` スナップショットを保存してデザインを検討できます。`scratch new` で候補を記録し、`scratch list`/`show` で確認します。`candidate` でライフサイクルを変更し(draft → selected | rejected)、`promote --into ` で選択した候補を納品物に統合し、`finalize` で却下された候補を破棄します。`bundle`/`unbundle` では、ドキュメント単位のストア全体(履歴+スクラッチ)を、ポータブルで決定論的な `.zenithbundle` にまとめる/展開できます。 - **ライブラリサブシステム** — プリセットパック(`@zenith/flowchart`、`@zenith/filters`、`@zenith/masks`、`@zenith/brand-kit`)を埋め込みで提供します。`library add` は、`libraries` と `provenance` の追跡情報を含む、自己完結型のドキュメントにアイテムを展開します。`zenith library show #` で任意のアイテムを確認できます。 - **AI アセットの来歴** — 画像モデルで生成した画像/イラストを `asset` として取り込む際、Zenith はその作成方法を記録します。記録される項目は `ai-prompt`、`ai-model`、`ai-provider`、`ai-seed`、`ai-license`、`ai-source-rights`、`ai-safety-status`、`ai-reuse-policy` です(`sha256` によるコンテンツロックも併せて記録します)。すべてのフィールド一覧は `zenith schema asset` を実行すると確認できます。 - **可変データの差し込み** — `role="data."` のバインディングにより、テキスト列と画像列、および複数ページのテンプレートを対象とする CSV 差し込み印刷ができます。行ごとの JSON レポートと、バイト単位で再現可能なマニフェストも生成します。 - **自己記述型 CLI** — `zenith schema` は、作成可能な要素(すべてのノード種別とその属性、トランザクション操作セット、トークン種別、および `page`/`asset`/`document`/`variant`/`diagnostics`/`brand` の各要素)を、人間が読める形式または `--json` で出力します。これにより、エージェントは推測に頼らず CLI 自体から作成可能な内容を把握でき、`zenith validate` が提供する具体的な診断情報と組み合わせて修正を進められます。

検証 — 安全網

70 件以上のチェック(エラー/警告/参考情報)で、レンダリングや印刷の前に問題点、リスク、ブランドイメージにそぐわない点を検出します。

zenith validate file.zen は、デザインファイルを安全に編集し、安心して納品できるようにするためのステップです。ドキュメント向けのコンパイラーの型チェッカーのようなもので、ソースを読み取り、レンダリングや印刷の前に問題点、リスク、ブランドイメージにそぐわない点をすべて報告します。そのため、何かが壊れていないか確かめるために、エージェント(またはあなた)が「レンダリングして目視で確認する」必要はありません。

70 件以上のチェックを実行し、それぞれを、安定したコード(例:text.overflow)、人が読めるメッセージ、問題のあるノード ID、ソース内の位置を含む診断として報告します。各診断には、次の 3 種類の重大度のいずれかが割り当てられます。

重大度意味影響
エラー不正な出力を引き起こす明確な問題レンダリングをブロック — 修正されるまで render は拒否され、validate は 0 以外の終了コードを返します
警告問題の可能性が高い、またはリスクのある構造出力は生成されますが、確認をおすすめします
参考情報情報提供のための注記ブロックすることはありません。参考情報です

実際のチェック内容は、平易に言うと次のとおりです。

  • 構造と参照の解決 — すべてのノード ID が一意で、すべての参照が実在する対象を指していることを確認します。対象にはトークン参照、画像アセット、コネクターのターゲット、フィールド、マスター/セクションが含まれます(id.duplicate、token.unknown_reference、asset.unknown_reference、connector.missing_target)。リンク切れや、何も表示されないままになる誤記を検出します。
  • デザインシステムの規律 — 視覚的なプロパティには、生の 16 進数ではなくトークンを使用する必要があります(token.raw_visual_literal)。これにより、ブランドの変更を 1 回の編集で行えます。また、循環参照、型の誤り、未使用のトークンも検出します(token.cyclic_reference、token.type_mismatch、token.unused)。
  • はみ出しやオーバーフローの防止 — ジオメトリが指定され、キャンバス内に収まっていること、テキストが実際にボックス内に収まること、子要素がフレーム内に収まっていること、コンテンツがページの余白とセーフゾーンを守っていることを確認します(node.missing_geometry、text.overflow、text.fit_failed、frame.child_overflow、margin.violation、safe_zone.violation)。アンカーは、実在する参照フレームに解決される必要があります(anchor.unresolved_sibling、anchor.cycle)。
  • 読みやすさと印刷対応 — テキストと背景のコントラストを**WCAG 3(APCA)**に照らして確認します(contrast.low)。また、PDF が実際に印刷できるよう、色空間、塗り足し、ページの偶奇を検証します(document.invalid_colorspace、page.invalid_bleed)。
  • モデルの整合性 — 新しい variants、recipes、provenance ブロックもチェックし、生成物や派生物の一貫性を保ちます(variant.unknown_source、recipe.unknown_palette_token)。

重要な理由:

  • 人にとって — 書き出し後ではなく、その前に「見出しがページからはみ出している」「このグレー同士の組み合わせは読みにくい」「この色はブランドトークンではない」「印刷ファイルの色空間が間違っている」といった問題を検出できます。
  • エージェントにとって — zenith validate --json は、正確で機械可読な契約です。エージェントはソースを編集して検証し、変更が妥当かどうかを把握できます。これが、手を介さない編集を安心して任せるための安全網になります。

エージェントのループ:作成 → 検証 → レンダリング → 点検 → 編集

Zenith によるレンダリング — ソース:assets/showcase/loop.zen。

### 知覚
レンダリングから測定した決定論的なシグナルです。好みではなく、シグナルです。美的スコアも、ビジョンモデルも使用しません。

zenith perceive page file.zen [--page N | --all-pages] [--json] は、zenith render --png と同様に、各ページをスケール 1 でレンダリングします。その後、トリムボックスを測定します(塗り足しは切り取られます)。zenith perceive vector は、代わりにソースからパスの形状を測定します。

出力はピクセルと宣言されたジオメトリを記述します。デザインの品質を判定するものではありません。根拠として読み取り、そのうえで判断してください。

指標測定内容
histogram最小値、最大値、平均値を含む、10 分割の Rec.709 輝度ヒストグラムです。
value_zones各ゾーン(1/3 未満のシャドウ、2/3 未満の中間調、それ以上のハイライト)ごとのピクセル数、平均値、ばらつきです。
density_map最大 4 × 4 セルでの輝度コントラストのエネルギー、最も強いセル、エネルギーの 70/20/10 の内訳です。
edge_map隣接ピクセル間の輝度の段差です。0.25 以上はハード、0.03 未満は失われたものとして扱います。
optical_balanceインクの中心とページの中心とのずれを、px とページに対する割合で示します。
clearspaceインクからページの各辺までの距離を、宣言された最小ページ余白と比較します。
grid_conformance最上位ノードのボックスの角(および全体の外接範囲の角と中心)から、最も近い構築ガイドまでの最大距離です。

インクとは、ページ上で最も多いピクセルと異なるすべてのピクセルです。

--json の読み方:

  • schema は 1 です。互換性を損なう形状の変更では、この値が増えます。エンベロープにはツールのバージョンが含まれないため、リリースによってバイト列は変わりません。
  • pages[].metrics.<name>.status は measured または not_applicable です。not_applicable の指標には reason が含まれます。
  • clearspace には 4 つすべての余白、margin-top、margin-bottom、margin-inner、margin-outer(ページまたはドキュメント)が必要です。grid_conformance には、segment または circle ガイドを含む construction ブロックが必要です。どの指標も、しきい値や入力を独自に設定することはありません。
  • 測定された各指標には、code、severity(info または warning)、message を含む diagnostics 配列があります。
  • 整数以外のすべての数値は、decimals(4)で指定された桁数に、0 から遠ざかる方向へ丸められます。
  • ページの測定が成功すると、終了コードは 0 になります。知覚の診断はシグナルであり、コマンドが失敗する原因にはなりません。ハードバリデーションエラーは処理を中断します。これは render の場合と同じです。

決定性:同じドキュメントからは、どのターゲットでも同じバイト列が生成されます。zenith-cli/tests/perceive_hashes.json には、Linux x64 および arm64、macOS arm64 および x64、Windows x64 で、すべての例から生成される出力が固定されています。MCP では、同じエンベロープが zenith_perceive(doc、page、all_pages)として公開されます。

バリエーション

1 つのデザインから複数の出力を生成する 2 つの方法:zenith variant(サイズ)と zenith merge(データ)です。

1 つのデザインから複数の出力を生成する、相補的な 2 つの方法です。一方はサイズを変え、もう一方はコンテンツを変えます。

正方形、ストーリー、バナーの各サイズでレンダリングした 1 つの標準デザイン

Zenith でレンダリング — ソース:assets/showcase/variants.zen。

### サイズ/形式のバリエーション(`zenith variant`)

variants ブロックを使うと、1つの標準ページから、名前付きのターゲットサイズを展開できます。各ターゲットでは、.zen の関連ファイルと PNG または SVG 画像が生成されます。ターゲットごとの override で、表示状態、テキスト、視覚的なプロパティを変更できます。ソーストークンの編集は、すべてのバリエーションに反映されます。アンカーされたノードは、それぞれのサイズに合わせて再配置されます。

variants {
  variant id="square" source="page.main" w=(px)1080 h=(px)1080 {
    override node="qr" visible=#false
  }
  variant id="story" source="page.main" w=(px)1080 h=(px)1920 { }
}
zenith variant poster.zen --out-dir out/ --manifest manifest.json
zenith variant poster.zen --out-dir svg/ --format svg --raster-scale 2
バッチフラグ仕様
--format png|svgPNG または SVG を選択します。デフォルトは PNG です。SVG のバリエーションには .zen の関連ファイルも含まれます。
--raster-scale FSVG のみ。有限値の 0 < F <= 4 を指定します。デフォルトは 1 です。
--manifest PATH失敗ステータスの部分的なエントリを含め、コミットされた出力を記録します。

バッチコマンドに --deny フラグはありません。フォールバック診断は、ドキュメント、ローカル、グローバルのポリシーに従います。フォールバックが拒否されると、そのバリエーションへの書き込みは行われません。I/O エラーが発生した場合、それ以前の出力が残ることがあります。バッチ全体のロールバックはありません。

生成は決定論的です(同じソース → バイト単位で同一の出力とマニフェスト、schema: zenith-variant-manifest-v1)。

データの差し込み印刷(zenith merge)

1つのテンプレートと CSV から、各行につき1つのレンダリング済みデザインを生成します。ローカライズされた投稿、パーソナライズされたグラフィック、証明書、キャンペーン用バリエーションなどに利用できます。可変のテキスト/画像ノードに role="data.<column>"(列名は CSV のヘッダー)を設定してから、差し込み印刷を実行します。

# in poster.zen — bind the headline to the CSV "name" column:
text id="hero.name" role="data.name" x=(px)60 y=(px)160 w=(px)680 h=(px)90 fill=(token)"color.ink" font-family=(token)"font.body" font-size=(token)"size.heading" { span "Name" }
zenith merge poster.zen people.csv --out-dir out/ --name-by name --manifest manifest.json
zenith merge poster.zen people.csv --out-dir svg/ --name-by name --format svg --raster-scale 2

差し込み印刷のデフォルト形式は PNG です。複数ページの場合、ファイル名では .png または .svg の前に -page-N が付きます。SVG のフォールバック診断は、ドキュメント、ローカル、グローバルのポリシーに従います。フォールバックが拒否されると、その行への書き込みは行われません。I/O エラーが発生した場合、それ以前にコミットされた出力が残ることがあります。レポートには、それらのパスが保持されます。

各行は個別に、決定論的にレンダリングされます。--name-by は列の値でファイル名を付けます(Alice.png、Bob.png)。--manifest は、CI 用にバイト単位で再現可能なバッチ記録(テンプレートとデータのハッシュ、および行ごとの来歴)を書き出します。画像列にも対応しています。role="data.logo" を設定した画像ノードは、行ごとにアセットパスを切り替えます。

## コネクター
端点がfrom/toノードから導出されるセマンティック矢印 — 自動ルーティング、矢印の先端、自己ループ、ラインジャンプ。

connectorは2つのノード間のセマンティック矢印です。記述されたジオメトリはありません — fromとtoにノード ID を指定すると、コンパイル時にエンジンがそれぞれの端点を、対象ノードの解決済みボックスから導出します。どちらかのボックスを動かすと、コネクターは自動的に再ルーティングされます。同じソースからは常に同じパスが生成されます。これはストロークのみのリーフで、塗りつぶしも子要素もありません。描画にはstrokeの色が必要です。

  • 端点のアンカー — from-anchor / to-anchorで各端点の接続位置を指定します。シンプルなフローチャートでは名前付きグリッドアンカー(top-left、bottom、center-right)を、複数のリンクを1つの形状の周囲に配置する洗練された図では、35/60のような分割アウトラインアンカーを使います。分割アンカーは上中央から始まり、時計回りに進みます。楕円では周囲の線上を、長方形では各辺の長さに沿って配置されます。デフォルトのautoは、もう一方のボックスを向いた辺を選びます。
  • ポート — ページではports { port node="agent" id="memory.vector" anchor="38/60" }のように、セマンティックな接続点を宣言できます。コネクターではfrom="agent#memory.vector"やto="store#in"のように指定できます。コンポーネントのポートはインスタンスを通じて投影されるため、connector from="agent.instance#out"は座標をコピーせずにコンポーネント内部のジオメトリに結び付いたままになります。
  • ルートモード(route=)— straight(デフォルト)は直線を描画します。orthogonalは直角の折れ線を描画します。avoidは障害物を避ける直交ルーターを使い、他のノードボックスを迂回するパスを描画します(明確な経路がない場合は通常の折れ線にフォールバックします)。
  • 自己ループ — fromとtoが同じノードを指定している場合、コネクターは片側に小さなループを作ります(側はアンカーから決まり、デフォルトはtopです)。
  • 矢印の先端 — marker-start / marker-end = arrowで、ストロークと同じ色の塗りつぶされた矢印の先端を追加します(デフォルトはnoneです)。先端は実際にルーティングされたセグメントに沿って向きが調整されるため、軸に沿って配置されます。
  • ラインジャンプ — ページレベルでline-jumps="arc"またはline-jumps="gap"を指定すると、コネクターは交差箇所で跳ね上がります。交差する線には、小さな半円状の膨らみ(arc)または途切れた隙間(gap)ができ、矢印の重なりが分かりやすくなります。動作は決定的で、水平線が垂直線を飛び越えます。ネストされたコネクターにも適用されます。指定がない場合(none / デフォルト)は、バイト単位で同一に描画されます。
  • スタイル設定 — 他のプリミティブと同じプロパティ/スタイルのカスケードに従い、stroke(必須)、stroke-width、opacity、rotate、およびstyle参照を指定できます。
page id="pg" w=(px)640 h=(px)360 line-jumps="arc" {
  ports {
    port node="n.start" id="out" anchor="1/4"
    port node="n.end" id="in" anchor="3/4"
  }
  shape id="n.start"  kind="process" x=(px)40  y=(px)150 w=(px)130 h=(px)60 fill=(token)"c.node" stroke=(token)"c.line" { span "Start" }
  shape id="n.end"    kind="process" x=(px)470 y=(px)150 w=(px)130 h=(px)60 fill=(token)"c.node" stroke=(token)"c.line" { span "Finish" }
  shape id="n.block"  kind="process" x=(px)290 y=(px)130 w=(px)70  h=(px)100 fill=(token)"c.block" stroke=(token)"c.blockline" { span "Block" }

  // Auto-routed flow bends around the Block instead of crossing it…
  connector id="e.flow"  from="n.start#out" to="n.end#in" route="avoid" marker-end="arrow" stroke=(token)"c.flow"  stroke-width=(token)"cw"
  // …and where a second connector crosses it, the page's line-jumps hops it.
  connector id="e.cross" from="n.top"   to="n.bottom" marker-end="arrow"               stroke=(token)"c.cross" stroke-width=(token)"cw"
}

実行可能なドキュメントの全体例は、examples/connector-routing.zenを参照してください。

## アイコンとライブラリ
再利用可能なパックは、.zen ファイルまたは *.svg のプレーンなディレクトリの2形式です。Lucide のアイコンセット全体(1745 個のアイコン)が組み込みで含まれています。

パックは名前付きのアイテムをエクスポートし、<package>#<item> で指定します。アイテムは zenith library add でドキュメントに実体化されます。アイテムには component(instance として配置されるノードグループ)、token(フィルター/マスクトークン)、action(定型のトランザクション)の3種類があります。

パックは次のいずれかの形式で保存されます。

  • .zen ファイル — トークン、コンポーネント、アクションを直接記述できる、機能豊富な形式です。library の自己エントリーで独自の識別情報を宣言します。
  • *.svg のディレクトリ — アイコンセット向けの、配置するだけでインストールできる形式です。各 *.svg が1つのアイコンで、その ID はファイル名(拡張子を除いた部分)です。記述作業は不要です。フォルダーを <project>/libraries/ に配置するとパックになり、@local/<dirname>#<stem> で指定できます。

SVG アイコンは追加時にネイティブの編集可能な path ノードに変換されます。不透明なラスター画像や <image> 参照として埋め込まれるわけではありません。他のジオメトリと同様に、インスタンスのオーバーライド(override ref="icon.0" stroke=(token)"brand" …)でスタイルを変更できます。変換は決定的かつ対象を限定して行われ、1つのアイコンを追加すると、そのアイコンだけが変換されます。

組み込みの @zenith/icons-lucide パックには、Lucide のアイコンセット全体(1745 個のアイコン、ISC AND MIT)が含まれています。列挙するには数が多すぎるため、検索を優先して見つけられるようにしています。

zenith library search sync                       # → refresh-cw (matched on its alias)
zenith library search arrow --category navigation
zenith library search cloud --kind component --limit 5
zenith library show  @zenith/icons-lucide#house  # format, license, aliases, tags, geometry
zenith library add   @zenith/icons-lucide#house --into poster.zen --page pg --at 40,40

検索結果は順位付けされ、単純な部分文字列検索ではありません。クエリに名前が一致するアイテムは、クエリに別名が一致するアイテムより上位になり、クエリにタグが一致するだけのアイテムよりさらに上位になります。そのため、home で検索すると lamp ではなく house が返されます。すべてのクエリ語が一致する必要があり、categories は順位付けではなく絞り込みに使われます。

アイコンと同じ場所にある任意の library.kdl で、識別情報と検索用メタデータを指定できます。指定がなくても、アイコンはファイル名で検索できます。

library id="@acme/icons" version="1.0.0" {
  license "CC0-1.0"
  icon "rocket-launch" aliases="liftoff" tags="spaceship booster" categories="space"
}

どちらの形式でも、プロジェクトのパックは、同じ ID を持つ組み込みパックより優先されます。

コマンド一覧

作成 · レンダリング · 編集 · バリアント · ライブラリ · テーマ · 履歴 · エージェント — すべてのコマンドで --json を指定できます。

フラグを確認するには zenith <command> --help を実行してください(各コマンドの説明と使用例が表示されます)。すべてのコマンドで、機械可読な出力を得るための --json を指定できます。

グループコマンド
作成new · validate · fmt · tokens · inspect
レンダリングrender(--png · --svg · --pdf · --scene · --all-pages · --all-pages-svg · --spread · --page)
認識perceive page(計測されたページシグナル。詳しくは認識を参照) · perceive vector(パスジオメトリのシグナル)
編集tx(型付きトランザクション。デフォルトではドライラン) · fix(診断に対する機械的な修正。デフォルトではドライラン) · edit(ブラウザーエディターとエージェント HTTP API。詳しくはブラウザーエディターを参照)
バリアントvariant(1つのデザインから複数のサイズ/形式を作成) · merge(CSV データの差し込み印刷)
ライブラリlibrary list · library search · library show · library add
テーマtheme new(ブランドカラーからトークンパックを合成)
履歴history · undo · redo · version · restore · sync
ワークスペースscratch new/list/show · candidate <status> · promote --into <page> · finalize · bundle/unbundle
エージェントplugin install · plugin uninstall · plugin list · mcp
## ブラウザーエディター
ブラウザーで .zen ファイルを編集できます。片側にソース、もう片側にレンダリングされたページが表示されます。ローカルサーバーまたは静的サイトで利用できます。

ソースペインが正となるデータです。キャンバスには、そのテキストをエンジンでレンダリングした結果が表示されます。キャンバスでの編集(移動、サイズ変更、回転、インスペクターフィールド)は、テキストを変更するトランザクションになります。

Zenith のブラウザーエディター。ソースペイン、テキストノードを選択したキャンバス、レイヤー、インスペクター、診断パネルが表示されています

キャンバスを全画面表示し、サイズ変更と回転のハンドルが付いたテキストノードを選択した Zenith のブラウザーエディター

診断パネルに不明なトークン参照がエラーとして表示され、ソースの該当行に下線が引かれている Zenith のブラウザーエディター

### `zenith edit`
zenith edit poster.zen

このコマンドは、1つのドキュメントをローカルポートで配信し、実行ごとに異なるトークン付きの URL を表示して、ブラウザーを開きます。ルートについては zenith edit --help を実行してください。

フラグ意味
--port <N>ポートです。デフォルト:空いているポートです。
--host <ADDR>バインドアドレスです。IP アドレスまたは localhost を指定します。デフォルトは 127.0.0.1 です。
--allow-remoteループバック以外の --host を許可します。通信はプレーン HTTP のため、トークンはネットワーク上を平文で流れます。SSH トンネル(ssh -L PORT:127.0.0.1:PORT host)または TLS リバースプロキシの使用を推奨します。
--root <DIR>エディターがプロジェクトファイルを読み取れるディレクトリです。デフォルトはドキュメントのディレクトリです。
--no-openブラウザーを開きません。
--json開始行を JSON として出力します:{schema, url, host, port, token, path}。

セキュリティモデル:

  • バインド。 デフォルトではループバックです。ループバック以外の --host には --allow-remote が必要で、通信がプレーン HTTP であることを警告します。
  • トークン。 OS の乱数生成器から取得した 64 桁の 16 進数で、実行ごとに新しいものが生成されます。すべての /api ルートには Authorization: Bearer <token> が必要です。サーバーはそれ以外の場所ではトークンを受け付けません。Cookie はポートを無視するため、127.0.0.1 上のすべてのサービスに届いてしまいます。
  • ページ URL。 http://127.0.0.1:PORT/#token=<token> です。ブラウザーはフラグメントをサーバーや Referer に送信しません。ページはトークンを読み取り、アドレスバーと履歴から削除して、メモリおよびこのタブの sessionStorage に保持します(再読み込み時にも機能します)。ページファイル自体は公開されており、トークンは不要です。
  • ブラウザーの起動。 トークンが起動コマンドラインに含まれることはありません。コマンドラインは他のローカルユーザーも読み取れるためです。サーバーは $XDG_RUNTIME_DIR(または一時ディレクトリ)にランダムな名前で 0600 のリダイレクトファイルを書き込み、そのファイルを開いて、最初の認証済みリクエストの後に削除します。サンドボックス化されたブラウザーがファイルを読み取れない場合は、表示された URL を開いてください。
  • Host と Origin。 Host は localhost、IP アドレス、または --host で指定した名前で、バインドされたポートを含む必要があります。それ以外の場合、サーバーは 403 edit.bad_host を返します。DNS リバインディングを使ったページはここで失敗します。リクエストに Origin がある場合は、http://<Host> と一致する必要があります。クロスサイトの fetch には 403 edit.bad_origin が返されます。サーバーは CORS ヘッダーを送信しません。POST の本文は application/json である必要があります。
  • 制限。 本文を読み取る前に、リクエストヘッダーとトークンを検証します。リクエストヘッダーは 5 秒以内に到着する必要があります。1つの接続につき1つのスレッドが処理し、同時接続数は最大64(リモートの同一接続元からは最大16)です。アイドル状態のクライアントが実際のリクエストを妨げることはありません。
  • ファイル。 サーバーが配信するのは埋め込み済みのページファイルのみです。エンジンは、ドキュメント、そのインポート、アセット、データ、テキストソースを、ドキュメントのディレクトリ(または --root)内からのみ読み取ります。.. およびディレクトリの外に出るシンボリックリンクはエラーになります。2つの読み取りはこの制限の対象外です。設定ファイル(最も近い .zenith.kdl と $HOME/.config/zenith/config.kdl)およびシステムフォントは、他の CLI コマンドと同じ方法で読み取られます。
  • 書き込み。 保存時にはコメントを保持し、履歴を記録し、tx --apply と同じ方法で doc-id を付与し、バイト列をディスクに同期したうえで、ファイルをアトミックに置き換えます。読み取り専用のドキュメントを開くと警告が表示されます。ページでは保存が無効になり、ファイルを書き込み可能にする方法が示されます。

サーバーは Ctrl-C または POST /api/shutdown を受け取るまで実行されます。未保存の編集がある場合、{"force": true} が指定されていない限り、シャットダウンは 409 を返します。正常終了するセッションでは、Ctrl-C、SIGTERM、SIGHUP により直ちに終了コード 0 で停止します。未保存の編集がある場合、最初のシグナルでは何も停止せず、ターミナルにファイル名が表示され、ページに[保存]ボタン付きのバナーが表示されます。2回目のシグナルでは編集を破棄して、終了コード 130 で終了します。

エディターの使用
  • レイアウト。 ソースとキャンバスは横に並びます(画面が狭い場合は縦に並びます)。仕切りをドラッグするか、仕切りにフォーカスして矢印キーを使うと、サイズを変更できます。全画面表示ボタンを押すと、どちらかのペインを拡大できます。Esc キーを押すと元に戻ります。ツールバーのボタンでは、ページとレイヤーのパネル、インスペクター、診断パネルを非表示にできます。レイアウトとテーマ(システム、ライト、ダーク)はブラウザーごとに保存されます。
  • キャンバス表示。 + と - でズームし、0 で 100% 表示、1 でページ全体を表示します。Ctrl または Cmd キーを押しながらホイールを操作するか、ピンチすると、ポインターを中心にズームします。ホイール、2 本指での操作、Space キーとドラッグ、または中央ボタンでパンできます。キャンバスは表示領域のみをデバイス解像度で描画します。
  • 選択。 ノードをクリックすると選択できます。Shift キーを押しながらクリックすると、選択に追加されます。空のキャンバス上でドラッグすると、範囲選択できます(Alt キー:範囲内に完全に収まるノードのみ、Shift キー:追加)。レイヤー、ソースカーソル、キャンバスでは、選択が共有されます。
  • 移動、サイズ変更、回転。 ノードまたはハンドルをドラッグします。Shift キーを押すと、軸を固定し、アスペクト比を維持するか、15 度刻みで回転します。Ctrl または Cmd キーを押すと、中心を基準にサイズを変更でき、移動時のスナップが無効になります。Alt キーを押すと、トークンにバインドされた値またはアンカーが解除されます。編集はボタンを離したときに適用されます。ゴーストの輪郭とライブプレビューがポインターに追従します。
  • スナップ。 マグネットボタンで、他のノードやページへのスナップを切り替えます。
  • 選択中のキーボード操作。 キャンバスにフォーカスがあるときに、次のキーを使えます。まずキャンバスをクリックしてください。矢印キーで 1 px 移動します(Shift キー:10 px)。Ctrl または Cmd キーと矢印キーでサイズを変更します。[ と ] で 15 度回転します。Delete または Backspace キーで削除します。Esc キーでドラッグをキャンセルするか、選択を解除します。選択されていない場合、矢印キーでパンします。
  • インスペクター。 選択したノードを表示し、カラートークンによる塗りつぶしや線など、そのフィールドを編集できます。
  • ショートカット。 Ctrl または Cmd キーと次のキーを組み合わせます。S で保存、Z で元に戻す、Shift+Z または Y でやり直し、D で選択範囲を複製、O でファイルを開きます(静的サイト)。元に戻す/やり直しの履歴には、入力とキャンバスの編集の両方が含まれます。
  • 診断。 下部のパネルにエラー、警告、注意事項が表示されます。位置情報のある行をクリックすると、ソース内の該当箇所に移動します。
  • 保存と競合。 保存すると、テキストがディスクに書き込まれます。ディスク上のファイルが変更されている場合、未編集のセッションではファイルが再読み込みされます。未保存の編集があるセッションでは競合の通知が表示されます。「Reload」を選択するとディスク上のテキストが読み込まれ(元に戻すと編集内容が復元されます)、「Overwrite」を選択するとエディターのテキストが書き込まれます。未保存の編集がある状態でタブを閉じようとすると、ブラウザーが確認を求めます。
信頼できる情報源
  • ソースペインに入力した内容が上書きされることはありません。エンジンはキー入力を失わずに、その他の変更(キャンバス、エージェント、ディスク)をペインにマージします。
  • キャンバスやインスペクターでの編集は、テキストにそのままパッチとして適用されます。コメントやレイアウトは維持されます。パッチを正確に適用できない場合、エンジンはドキュメントを標準形式で書き換え、コメントが失われることを警告します。元に戻すとコメントが復元されます。これは、編集箇所のレイアウトに正確なパッチを適用できない場合に発生します。たとえば、他のテキストと同じ行にあるノード、インラインの { ... } 子ブロック、新しいトップレベルノードなどが該当します。ノードを削除すると、その直上にある // コメント行も削除され、その旨がページに表示されます。
  • ソースにエラーがある間、キャンバスには最後に有効だった描画が「Showing last valid preview」と表示され、診断パネルにはエラーが一覧表示されます。
静的サイト

エディターは静的サイトとしても動作します。エンジンは WebAssembly モジュールとして Worker 内で動作します。サーバーは関与しません。ドキュメントはユーザーのディスクから開き、そこに保存し直します。

サイトをビルドします:

cargo build --target wasm32-wasip1 -p zenith-editor-wasm --profile release-wasm
node zenith-cli/scripts/build-static-editor.mjs --out dist/editor

スクリプトは target/wasm32-wasip1/release-wasm/(または $CARGO_TARGET_DIR)からモジュールを読み込みます。別のファイルを指定するには --wasm <file> を渡します。ページ、モジュール、バンドルされたフォント、samples/(サンプル)を --out にコピーします。すべての URL は相対パスなので、サイトはサブディレクトリに配置できます。たとえば python3 -m http.server -d dist/editor など、任意のファイルサーバーを使ってローカルでテストしてください。

ホストの要件:

  • https:// または http://localhost で配信してください。File System Access のピッカーと crypto.subtle にはセキュアコンテキストが必要です。
  • .wasm を application/wasm として配信してください。種類が正しくなくても読み込めますが、ストリーミングコンパイルは行われません。
  • script-src で 'wasm-unsafe-eval' を許可してください。ブラウザーはこのソースのもとでモジュールをコンパイルします。
  • 同じオリジンからの Worker を許可してください:worker-src 'self'。Worker スクリプトは js/engine/wasm/worker.js です。
  • img-src で blob: と data: を許可してください。ページは blob から PNG を描画します。
  • connect-src 'self' を維持してください。ページは同じオリジンからモジュール、フォント、サンプルを取得します。
  • build-static-editor.mjs は、このポリシーを設定した _headers ファイル(Netlify と Cloudflare Pages 用)を書き込みます:default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; worker-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' blob: data:; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'。その他のホストでは、同じヘッダーを手動で設定する必要があります。

動作:

  • ページは起動時に使用するホストを選択します。<meta name="zenith-host" content="wasm">(ビルドによって書き込まれます)が wasm エンジンを選択します。このメタタグがない場合、ページは /api/state に一度問い合わせます。zenith edit が応答し、ページはそのエンジンを使用します。
  • ツールバーのボタンで .zen ファイルまたはプロジェクトフォルダーを開きます。フォルダーを開くと、ドキュメントでインポートとアセットを利用できます。Chromium では保存内容がファイルに書き戻されます。その他のブラウザーでは <input type=file> で読み込み、ダウンロードで保存します。
  • Noto Sans Regular と Bold 以外のバンドル済みフォントは、必要に応じて fonts/ から読み込まれます。
  • ?doc=samples/<name>.zen でサンプルを開きます。デフォルトは samples/stack.zen です。
  • エンジンを呼び出すたびに、セッションとプロジェクトファイルがモジュールに送信されます。プロジェクトフォルダーには大きな画像を入れないでください。
  • 静的サイトで保存しても、ファイルに doc-id は書き込まれません。
エージェントと MCP

エージェントはページに表示されているものと同じセッションを操作します。HTTP では、POST /api/cmd でエディターコマンドを実行します({"command":"commands.list"} でコマンド一覧を取得できます)。エージェントによる編集はページにリアルタイムで反映されます。MCP では、6 つのツールでエンジンを利用できます。開閉できるのは .zen ファイルのみです。読み取りルートはドキュメントのディレクトリ(または root)です。サーバーを zenith mcp --root / で起動しない限り、読み取りルートとしての / は拒否されます。サーバーは最大 16 個のセッションを保持します。新しいセッションを開始すると、未保存の編集がない中で最も長く使用されていないセッションが削除されます。

ツール目的
zenith_editor_openエディターセッションで .zen ファイルを開きます。セッション ID を返します。編集済みのセッションを再度開くには discard=true が必要です。
zenith_editor_commandセッションでエディターコマンドを 1 つ実行します(select.hit、gesture.commit、tx.apply、history.undo、file.save など)。テキスト編集にはセッションの version が必要です。
zenith_editor_renderセッションのページを PNG にレンダリングします。テキストにエラーがある場合は、最後に有効だったテキストをレンダリングします(stale: true)。
zenith_editor_sessionsセッションの一覧を表示します:ID、種類(ローカルまたは接続済み)、パス、バージョン、編集状態、有効性、競合。
zenith_editor_closeセッションを閉じます。未保存の編集がある場合は discard=true が必要です。接続済みのセッションを閉じても、登録が解除されるだけです。
zenith_editor_attachこのマシンで実行中の zenith edit に接続し、ページを見ている人がエージェントの編集を確認できるようにします。表示された URL を渡します。
## 履歴とバージョン
ドキュメントごとのローカル編集履歴(スナップショット、取り消し/やり直し、永続的な名前付きバージョン)— レンダリング処理には一切影響しません。

Zenith は、レンダリング処理には一切影響しない、ドキュメントごとのローカル編集履歴を保持します。ピクセルが変化することはありません。最初の編集時に、ドキュメントには安定した識別子が付与されます。これはファイルに記録され、レンダラーからは無視される ULID の doc-id です。それ以降、エンジンによるすべての編集(tx --apply、library add、undo/redo/restore)は完全なスナップショット(操作ログではなく状態)として記録されるため、手動編集を行った場合でも履歴が保持されます。

zenith tx poster.zen recolor.json --apply   # an edit — recorded automatically
zenith undo poster.zen                       # step back, rewriting the file in place
zenith redo poster.zen                       # step forward again
zenith history poster.zen                    # list the timeline (--json for tooling)

zenith version poster.zen "launch-v1"        # save a NAMED version, kept indefinitely
zenith restore poster.zen launch-v1          # rewrite the doc to that version
zenith restore poster.zen @head~1            # …or to a revspec: v2, @head~1, @latest:named, a name

zenith sync poster.zen                        # capture an out-of-band change (GUI / hand-edit / git checkout)

履歴には 2 つの層があります。取り消し/やり直しは、一時的なセッションのタイムラインをたどる機能で、進行中の作業に適した高速なローカル操作です。名前付きバージョンは、SHA-256 と DEFLATE を使用した永続的なコンテンツアドレス指定チェックポイントで、削除するまで保持されます。restore を使うと、任意のバージョンに移動できます。エンジンの外部で行った編集を履歴に取り込み、履歴を完全な状態に保つには sync を使用します。履歴の記録はベストエフォートです。書き込みに失敗してもファイルは保存され、編集が妨げられることはありません。

コーディングエージェントでの使用

zenith plugin install で Claude Code/Codex/OpenCode/Cursor/…用のスキルをインストールし、リモート/CI 用の MCP サーバーも利用できます。

Zenith には、AI コーディングエージェントに CLI の操作方法を教えるスキルが付属しています。エージェントによる作成 → 検証 → レンダリング → 編集のループ、デザインのレシピ、そして --help では伝えきれないトークン/ブランドの規律を学べます。使用するエージェントにインストールしてください。

zenith plugin install                  # auto-detect installed agents, install for your user
zenith plugin install --claude --codex # choose specific agents
zenith plugin install --all            # every supported agent
zenith plugin install --claude --scope project   # into ./ for one repo
zenith plugin list                     # see what's installed where

Claude Code、Codex、OpenCode には、完全なフォルダ形式のスキル(リファレンスパック、テンプレート、テーマ)が提供されます。その他のエージェント(Cursor、Windsurf、Aider、Zed、Gemini、Copilot、Continue、Kiro、Antigravity)には、自己文書化機能を備えた CLI を参照する、自己完結型の単一ルールファイルが提供されます。一致するファイルは変更されません。インストール済みのアセットをアップグレードするには、次のコマンドを実行します。

zenith plugin install --force

--force を指定すると、ユーザーによる変更を含む、インストール済みの異なるファイルが上書きされます。指定しない場合、異なるファイルは変更されません。インストールを削除するには、zenith plugin uninstall を実行します。

MCP サーバー(リモート/CI/ホスト型エージェント)

Model Context Protocol を通じて機能を検出するエージェント、または CI やホスト型/SaaS パイプライン向けに、Zenith は第一級の MCP サーバーとして動作します。これは単なる CLI ラッパーではありません。ツールの結果は不要な情報を省いた構造化 JSON で返され、スキーマの詳細は単一の zenith_schema ツールを使って必要に応じて取得するため、モデルがすべてのノード/操作スキーマを保持する必要はありません。大きな成果物やバイナリ成果物(レンダリング結果、大きなツリー、差分)はインラインで返されるのではなく、コンテンツアドレス指定ストアへのリソースリンクとして返されます。また、ドキュメントは doc-id で指定できるため、エージェントがパスを管理する必要はありません。作成の全工程が公開されており、zenith_schema、zenith_validate、zenith_inspect、zenith_tokens、zenith_tx、zenith_fix、zenith_render、zenith_perceive、zenith_fmt、zenith_merge、zenith_theme_new に加え、スクラッチ/候補/昇格/確定用のワークスペースツールが利用できます。ポインタースタイルの編集(ヒットテスト、ドラッグ、取り消し、ライブレンダリング)には、ブラウザーエディターで説明されている zenith_editor_* ツールを使用します。

MCP レンダリングパラメーター仕様
format必須:png、svg、pdf、または scene。
page1 から始まります。既定では、PDF の場合は全ページ、それ以外の形式では 1 ページ目が対象です。
raster_scaleSVG/PDF のフォールバック解像度です。有限の 0 < F <= 4 を指定でき、既定値は 1 です。
scale / contact_sheetPNG のみで使用できます。
out任意の保護対象ファイルへの書き込みです。成果物のリソースリンクと併せて使用できます。
diagnosticsソフト診断を含めます。false の場合も、フォールバックのレポートは表示されます。

MCP の zenith_merge は format: png|svg に対応しており、既定値は PNG です。SVG では有限の raster_scale 値を 0 < F <= 4 の範囲で指定でき、既定値は 1 です。ドキュメント単位、ローカル単位、グローバル単位のバッチポリシーが適用されます。構造化レスポンスには、コミットされたパスと部分的な行が保持されます。マニフェストの書き込みエラーが発生した場合も行数が保持され、ツールの結果はエラーとして示されます。MCP 版のツールはありません。

stdio(既定のトランスポート)で実行します。

zenith mcp

対応する MCP クライアントから接続します:

{
  "mcpServers": {
    "zenith": { "command": "zenith", "args": ["mcp"] }
  }
}

…または、Claude Code の場合:claude mcp add zenith -- zenith mcp。

リモート/ホスト型での提供。 オプションの http 機能を有効にしてビルドすると、単一の /mcp エンドポイントでネイティブの Streamable-HTTP を提供できます。トランスポートは zenith edit と同じ、上限が設定された std::net HTTP レイヤーで動作し、依存関係は追加されません:

cargo install --path zenith-cli --features http --locked
zenith mcp --http 127.0.0.1:8080     # prints the token to stderr
# test it:
curl -s -XPOST http://127.0.0.1:8080/mcp \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

ツールはファイルの読み書きを行うため、HTTP トランスポートはリクエスト本文を読み取る前に、すべてのリクエストを検証します:

  • バインド。 ループバックのみです。--allow-remote を指定すると、別のアドレスからの接続を許可します。通信は平文 HTTP です。前段に TLS リバースプロキシを配置してください。
  • トークン。 Authorization: Bearer <token> を使用します。トークンには ZENITH_MCP_TOKEN(32 文字以上)を使用し、設定されていない場合は起動時にランダムなトークンが生成され、stderr に出力されます。
  • Host と Origin。 Host は localhost、IP アドレス、--http のホスト、または --allow-host で指定した名前である必要があります。ブラウザーの Origin は同じホストを示す必要があります。
  • 本文。 Content-Type: application/json を指定し、サイズは最大 8 MiB です。
  • ルート。 すべてのツールパス(ドキュメント、出力、データ、バンドル)は --root の配下に置く必要があります。デフォルトは作業ディレクトリです。stdio では --root は省略可能です。ルートを設定すると、ドキュメントが読み取るすべてのファイル(インポート、アセット、データ、ローカルの .zenith.kdl)はルートの配下に制限されます。ユーザーレベルのグローバル設定($HOME/.config/zenith/config.kdl)とシステムフォントは制限されません。

ワークスペースストア(スクラッチ候補、バージョン履歴、レンダリング済みリソースアーティファクト)は $XDG_DATA_HOME/zenith(デフォルトでは ~/.local/share/zenith)に保存されます。分離環境やホスト型デプロイで保存先を変更するには、ZENITH_DATA_DIR を設定してください。

ローカルエージェントでは、MCP ではなく CLI とスキルを優先してください。 環境でバイナリを実行できる場合は、zenith plugin install で使い方を学習できる zenith の直接実行が最も速い方法です。リモートホスト、CI、サンドボックス、または読み取りと書き込みの全機能をプロトコル経由で利用したいホスト型/本番サービスなど、バイナリを実行できない環境では MCP サーバーを使用してください。そうした用途では、このサーバーが第一級の選択肢です。

リポジトリには server.json(MCP レジストリマニフェスト)が含まれています。手動の MCP の公開 ワークフローでは、選択した安定版タグに対応する npm ランチャーとレジストリエントリを公開します(GitHub OIDC を使用するため、レジストリトークンは不要です)。これにより、Zenith は MCP ディレクトリから見つけられるようになり、クライアントは npx -y @zenitheditor/zenith-mcp から起動できます。

  • MCP レジストリ名:mcp-name: io.github.zenitheditor/zenith
## ワークスペース
それぞれが単一の関心事を担うクレートで構成された Rust ワークスペースです。zenith-geometry は他の Zenith クレートに依存しません。

各クレートは単一の関心事を担い、安定した契約を公開します。zenith-geometry は他の Zenith クレートに依存しません。zenith-core は、これらのうち zenith-geometry のみに依存します。

Crate責務
zenith-geometry純粋なジオメトリ:パス、輪郭、ブーリアン演算
zenith-coreKDL パーサーアダプター、セマンティック AST、正規フォーマッター、コメント保持型ソースパッチャー、トークン、検証、診断
zenith-layoutテキスト整形とフォントメトリクス(rustybuzz + ttf-parser)。サードパーティ型はこのクレート内に限定
zenith-rasterラスターサーフェス、ブレンドモード、調整
zenith-perceptionジオメトリとラスターを対象とするビジュアル QA レポート
zenith-sceneバックエンド非依存のシーン IR とコンパイル(ジオメトリ、テキストの折り返し、アンカー、不透明度/クリップ、ヒットデータ)
zenith-renderCPU PNG バックエンド(tiny-skia)、SVG エクスポート、ベクター PDF バックエンド。決定性を強制
zenith-txトランザクション操作セット、適用/ドライランエンジン、差分、監査記録の契約
zenith-sessionローカルマシンでのドキュメント ID、セッション DAG、永続バージョン(コンテンツアドレス方式のストア)
zenith-zpxパッケージ化されたデザインのエクスポート(マニフェスト + ベイク)
zenith-producersより高レベルの生成/エクスポート用ヘルパー(ネイティブ SVG、ZPX ベイク)
zenith-pipeline設定ポリシー、インポート、フォント、アセット、検証、コンパイル、ホスト I/O トレイトを介したレンダリング。CLI と wasm エディターで共有
zenith-editorエディターエンジン:シリアライズ可能なセッション上で動作するステートレスなコマンドレジストリ。ブラウザー、zenith edit、MCP で共有
zenith-editor-wasm静的サイト向けの wasm32-wasip1 コマンドモジュールとしてのエディターエンジン(公開なし)
zenith-clizenith コマンドラインツール(クレート zenith-tool):ディスパッチ、引数解析、JSON/人間向け出力、MCP

リポジトリで活用

`.zen` ファイルは単なるテキストです。コミットして、PR でレビューし、CI でレンダリングし、ロールバックできます。

Zenith ファイルは単なるテキストなので、コードと同じ場所に置けます。git にコミットできます。プルリクエストでデザインの変更を差分と並べてレビューできます。CI でレンダリングして、リリース前にレイアウトの崩れを検出できます。パイプラインでバリエーションを生成できます。他のファイルと同じようにロールバックできます。デザインは、エクスポート先とエクスポート元を持つ別世界ではなく、ビルドの一部になります。

対象ユーザー

AI/エージェントの開発者、エンジニアリングチーム、大量生産を行う担当者、ツール開発者。
  • スクリーンショットを頼りに祈るのではなく、ビジュアルを確実に生成・編集したい AI およびエージェントの開発者。
  • リポジトリにデザインアセットを置き、PR でレビューし、CI でビルドしたい エンジニアリングチーム。
  • 正確なバリエーションを大量に必要とする 大量生産を行う担当者(マーケティング、出版、ローカライズ)。
  • クローズドなクラウド API ではなく、オープンフォーマットを基盤に構築したい ツール開発者。
## ショーケース
再利用可能な Zenith のサンプルは、zenith-showcase サブモジュールにあります。

公開ショーケースは zenitheditor/zenith-showcase にあり、zenith-showcase サブモジュールとしてここからリンクされています。

ここには、再利用可能な Zenith のサンプルを掲載しています。.zen ソース、レンダリング結果、ビジュアルレシピ、アクション、フィルター、背景、ポスター、チラシ、書籍、雑誌、広告、図表、プレゼンテーション、その他の生成されたデザイン作品が含まれます。

ショーケースには、共有する権利があり、提出したソース、出力、アセットを、明記されたライセンスの下で他の人が再利用することを許可できるファイルのみを掲載してください。非公開の作品、クライアント向けの作品、ポートフォリオ限定の作品、または独自ライセンスの作品は、ショーケースの外部ギャラリーからリンクしてください。外部作品のライセンスは、引き続き所有者が管理します。

ステータス

Zenith は、最初の公開リリースシリーズにあります。作成 → 検証 → 編集 → レンダリングのパイプラインはエンドツーエンドで動作し、解析、診断セット、トランザクションエンジン、PNG/SVG/PDF レンダリング、ローカル履歴、ライブラリサブシステム、可変データのマージが実装され、テスト済みです。プロジェクトの成熟に伴い、フォーマット、ワイヤー型、コマンドの仕様は今後変更される可能性があります。

コントリビューション

エンジンの開発方法については CONTRIBUTING.md を、拘束力のあるリポジトリ規約(人間とエージェントの貢献者双方にとっての信頼できる情報源)については AGENTS.md をご覧ください。各リリースの変更内容は CHANGELOG.md に記載されています。

ライセンス

Apache-2.0。LICENSE をご覧ください。同梱フォントは SIL Open Font License 1.1 の下で提供されています(zenith-core/assets/fonts/LICENSE.txt および zenith-fonts-fallback/OFL.txt を参照してください)。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。