关于 Zenith
Zenith 是面向 AI Agent 的设计文档格式与引擎,以纯文本 .zen 文件描述设计内容。同一文件始终渲染为相同像素,可输出 PNG、SVG 和 PDF。项目提供命令行工具,并支持 npm 安装的 MCP 包,适合需要可审查、可校验设计源文件的团队。
主要功能
- 01基于 KDL 的纯文本 .zen 设计格式
- 02校验诊断、格式化与设计令牌查看
- 03确定性渲染为 PNG、SVG 和 PDF
- 04通过类型化事务安全编辑设计源文件
- 05提供命令行与 Rust 库 crate
适用场景
- 01由 Agent 生成并校验海报、图表或社交图片
- 02在版本控制中审查设计变更的文本差异
- 03批量渲染多页文档或多个设计变体
MCP 相关
该项目提供 @zenitheditor/zenith-mcp 包,即 npm 发布的 MCP 服务,用于向 MCP 客户端暴露 zenith 引擎的功能。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Zenith
专为 AI Agent 时代打造的设计文档格式和引擎。
纯文本 .zen 设计文件,可供阅读、比较差异、审阅、验证,并让 Agent 安全编辑 — 确定性地编译为像素精确的 PNG、自包含 SVG 和可直接用于印刷的 PDF。
本 README 中的每一幅横幅和示意图都是使用 Zenith 创建的 — 源文件位于 assets/showcase/。
Zenith 是一种用于设计文件的纯文本格式和引擎,适用于海报、演示文稿、书籍、社交媒体图片、示意图等。理念很简单:设计应该像代码一样运作。 你应该能够阅读、比较差异、审阅、测试,并让 Agent 安全地编辑设计。
.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 个库 crate 以各自的名称发布: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 Releases
直接从 GitHub Releases 下载:
| 平台 | 架构 | 资源 |
|---|---|---|
| Linux | x86_64 | zenith-<version>-linux-x64.tar.gz |
| Linux | aarch64 | zenith-<version>-linux-arm64.tar.gz |
| macOS | x86_64 | zenith-<version>-macos-x64.tar.gz |
| macOS | Apple Silicon | zenith-<version>-macos-arm64.tar.gz |
| Windows | x86_64 | zenith-<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 | 默认将所有页面导出到一个 PDF 中。 |
--page N | 为单输出标志选择一个页面,包括 PDF。 |
--all-pages-svg DIR | 按文档顺序写入 page-N.svg。 |
--raster-scale F | SVG/PDF 回退分辨率。取值为有限数,满足 0 < F <= 4,默认为 1。 |
--scale F | PNG 输出缩放比例。取值为有限数,满足 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" }
}
}
}
参见 examples/,其中包含可运行的 .zen 文件,涵盖形状、富文本、内联 markdown(从外部文件加载)、代码块、图像、框架/组、多页文档和样式,以及更丰富的功能——gradient、shadow、blur、filter、mask、table、flowchart(形状 + 连接线)、图表(柱状图/折线图/面积图/饼图/圆环图/迷你图,支持图例、数值标签和数据绑定)以及 anchors。
为什么
代码有源代码管理、类型、测试和 PR,设计文件却什么都没有——这给人们带来了困扰,也阻碍了 AI。
代码有源代码管理、类型、测试和拉取请求。设计文件却什么都没有。它们是不透明的二进制文件——无法比较差异、无法评审更改,而且同一个文件在不同机器上的渲染结果可能不同。
这对人们来说是个问题,对 AI 来说问题更大。Agent 已经能编写代码并发起拉取请求,因为代码是它们可以阅读和推理的文本。让它们进入设计工具,它们就会两眼一抹黑。让 Agent“把标题改成品牌红色并收紧布局”,却没有任何安全可靠的操作对象——没有稳定的目标、没有验证、没有预览,也无法检查结果。
Zenith 解决了这个问题。我们的目标是让设计文件像代码一样可以安全地自动化处理:
- 纯文本,由你掌控——可读、可比较差异,并且永远属于你。
- 稳定 ID,让每项更改都是可评审的补丁,而不是鼠标拖拽。
- 确定性渲染——同一个文件始终生成相同的像素。
- 真正的验证——文本适配、颜色来自设计系统,而且没有内容溢出页面。
- 安全编辑——每项更改都是经过类型定义的事务,在应用前会经过检查并可预览,同时提供源文件差异和审计记录。
它不是 AI 图像生成
与图像模型正好相反:Zenith 生成的是可编辑的设计,而不是一张扁平图片。
这是最常见的误解,值得开门见山地说明:Zenith 与 Nano Banana、ChatGPT image 或 Grok Imagine 这样的图像模型正好相反。
图像生成器给你一张扁平图片。它只是一堆像素——你无法打开它来移动徽标,无法强制标题使用你指定的品牌颜色,而要求“同样的内容,只是日期不同”会得到另一张图片。没有任何东西可以编辑、评审或保证。
Zenith 不生成图片,而是生成_设计本身_——一份结构化、可编辑的文档,其中每个元素都真实存在且可定位。Agent(或人)可以修改一行内容、替换一个颜色令牌,或重新生成一百个符合品牌规范的变体,而且每次渲染都精准且可重复。AI 编写和编辑源文件;Zenith 则保证其含义和呈现效果。
Agent 原生优先,而不是事后加上 API 的工具
基础是程序化、确定性的引擎;可视化编辑器是其上的客户端——自动化才是入口。
大多数设计工具都是为人们拖拽方框而构建的,自动化 API 则是后来才添加的事后功能——它只是覆盖在一个本就不是为软件驱动而设计的模型之上的薄弱、受限层。
Zenith 则反其道而行。它的基础是程序化、基于文本的确定性引擎。Agent、脚本和命令行都能直接驱动它。因此,自动化不是侧门,而是正门。
编辑器。 引擎和 CLI 是 AI Agent 驱动的界面。浏览器编辑器是构建于同一引擎之上的客户端:设计师可以微调一个方框,Agent 可以调整一百个变体的样式,两者都基于相同的确定性核心运行,并使用相同的验证、事务和版本历史记录。GUI 并不是一个事后附加自动化功能的独立产品。
一条确定性流水线:解析 + 验证 → AST → 编译 → 场景 IR → 渲染(PNG/SVG/PDF)。
.zen 文档会经过一条统一的确定性流水线。每个阶段都是独立的 crate,拥有清晰的契约边界,因此 GPU 后端或编辑器都可以使用相同的场景 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` 格式** — 使用 KDL v2 源码,采用 `project` / `tokens` / `styles` / `document` / `page` 结构;每个节点都有稳定的 ID。 - **设计令牌** — 包括 `color`(sRGB **和**原生 CMYK)、`dimension`、`number`、`fontFamily`、`fontWeight`、`gradient`(线性/径向)、`shadow`、`filter` 和 `mask`,支持别名链和循环检测。 - **完整的节点集** — `rect`、`ellipse`、`line`、`polygon`、`polyline`、`text`、`code`、`image`、`frame`、`group`、`pattern`、`shape`、`connector`、`chart`、`instance`、`field`、`footnote`、`toc` 和 `table`,并可无损直通未知节点,以实现向前兼容。 - **真正的排版** — 使用 `rustybuzz` 进行字形整形,内置 Noto Sans / Noto Sans Mono,支持字体回退、Knuth–Liang 断词、富文本行内样式(粗体/斜体/下划线/删除线/高亮/行内代码/链接)、文本串接流排(链)、首字下沉、制表位前导符、文本环绕,以及字形不可用时触发的 `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" …` 声明控制(级联顺序:文本 > 页面 > 文档),因此 `.zen` 负责所有布局和样式,而 `.md` 文件只保留纯文本内容。对于超出单个文本框容量的长篇内容,可使用 `chain` 连接多个 `text` 节点以手动分页;内容无法完全容纳时会触发 `text.overflow` 警告。 - **视觉效果** — 线性与径向渐变、分层阴影、高斯模糊、羽化蒙版、12 种 Porter-Duff 混合模式、不透明度级联、逐角半径,以及图像适配/裁剪形状/对象位置。 - **锚点** — 相对于页面、安全区、父容器或同级节点的 9 点定位(优先级:区域 > 同级节点 > 父级 > 页面),全部转换为明确且确定的几何数据(未设置锚点时,生成的字节与手动放置坐标完全一致)。 - **程序化配方** — `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` 用于转换其生命周期状态(草稿 → 已选定 | 已拒绝),`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` 会以人类可读文本或 `--json` 的形式输出可创作内容(所有节点类型及其属性、事务操作集、令牌类型,以及 `page` / `asset` / `document` / `variant` / `diagnostics` / `brand` 接口),让 Agent 能直接通过 CLI 了解可创作的内容,而无需猜测;同时可结合 `zenith validate` 提供的可操作诊断,完成修复闭环。验证 — 安全网
70 多项检查(错误 / 警告 / 提示),可在渲染或打印之前发现问题、风险或不符合品牌规范之处。
zenith validate file.zen 是确保设计文件可安全编辑、值得放心交付的步骤。它就像编译器的类型检查器,不过针对的是文档:它会读取源文件,并在渲染或打印之前报告所有问题、风险或不符合品牌规范之处,这样 Agent(或你)就不用再靠“渲染出来仔细检查”来发现问题。
它会运行 70 多项检查,每项检查都会生成一条诊断信息,其中包含稳定的代码(例如 text.overflow)、易读的说明、出问题的节点 ID 和源文件位置。每条诊断信息都有以下三种严重级别之一:
| 严重级别 | 含义 | 影响 |
|---|---|---|
| 错误 | 确定存在问题,会导致输出错误 | 阻止渲染 — render 会拒绝执行,且 validate 会以非零状态退出,直到问题修复 |
| 警告 | 可能存在问题或有风险的结构 | 仍会生成输出;建议检查 |
| 提示 | 信息性说明 | 不会阻止操作;仅供参考 |
具体来说,它会检查:
- 结构和引用有效 — 每个节点 ID 都唯一,且每个引用都指向实际存在的对象:令牌引用、图像资源、连接器目标、字段、母版/版块(
id.duplicate、token.unknown_reference、asset.unknown_reference、connector.missing_target)。没有悬空链接,也没有导致内容悄无声息地无法渲染的拼写错误。 - 遵循设计系统规范 — 视觉属性必须来自令牌,而不是原始十六进制值(
token.raw_visual_literal),这样修改品牌风格只需改一处;它还会标记循环引用、类型错误或未使用的令牌(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)。
这为何重要:
- 对人来说 — 你可以在导出之前发现“标题跑出页面了”“灰字灰底看不清”“这个颜色不是品牌令牌”或“打印文件的色彩空间不对”等问题,而不是事后才发现。
- 对 Agent 来说 —
zenith validate --json提供精确、机器可读的契约。Agent 编辑源文件后进行验证,就能_确认_修改是否可靠 — 这张安全网让无需人工介入的编辑值得信赖。

由 Zenith 渲染 — 源文件:assets/showcase/loop.zen。
从渲染结果中测得的确定性信号。它们是信号,不是品味判断:不评审美,也不使用视觉模型。
zenith perceive page file.zen [--page N | --all-pages] [--json] 会以与 zenith render --png 相同的 1 倍比例渲染每一页,然后测量裁切框(出血部分会被裁掉)。zenith perceive vector 则直接从源文件测量路径几何形状。
输出描述像素和声明的几何信息,并非对设计质量的评判。请将其视为依据,再自行判断。
| 指标 | 测量内容 |
|---|---|
histogram | Rec.709 亮度直方图,分为 10 档,并提供最小值、最大值和平均值。 |
value_zones | 各区域的像素数、平均值和分布范围:阴影区低于 1/3,中间调低于 2/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需要提供全部四个边距:margin-top、margin-bottom、margin-inner和margin-outer(页面或文档级)。grid_conformance需要包含segment或circle辅助线的construction块。指标不会自行设定阈值,也不会虚构输入。- 每个已测量指标都有一个
diagnostics数组,其中包含code、severity(info或warning)和message。 - 每个非整数数值都会按远离零的方向四舍五入,保留
decimals(4)位小数。 - 页面测量成功时退出码为 0。感知诊断只是信号,永远不会导致命令失败。硬性验证错误会阻止该命令执行,就像它们会阻止
render一样。
确定性:相同文档在所有目标平台上都会产生相同的字节内容。zenith-cli/tests/perceive_hashes.json 固定了每个示例在 Linux x64 和 arm64、macOS arm64 和 x64,以及 Windows x64 上的输出。MCP 通过 zenith_perceive 暴露相同的信封(doc、page、all_pages)。
变体
根据一个设计生成多种输出的两种方式:zenith variant(尺寸)和 zenith merge(数据)。
根据一个设计生成多种输出的两种互补方式——一种改变尺寸,另一种改变内容。

由 Zenith 渲染——源文件:assets/showcase/variants.zen。
尺寸/格式变体(zenith variant)
variants 块可将一个规范页面扩展为多个命名的目标尺寸。每个目标都会生成一个 .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|svg | 选择 PNG 或 SVG。默认为 PNG。SVG 变体会保留 .zen 配套文件。 |
--raster-scale F | 仅适用于 SVG。取值有限,且满足 0 < F <= 4;默认为 1。 |
--manifest PATH | 记录已提交的输出,包括状态为失败的不完整条目。 |
批处理命令没有 --deny 标志。文档、本地和全局策略决定回退诊断行为。禁止回退时,该变体不会写入文件。I/O 错误可能导致先前的输出保留。批处理不支持回滚。
生成过程具有确定性(相同源文件 → 字节完全一致的输出和清单,schema: zenith-variant-manifest-v1)。
数据邮件合并(zenith merge)
一个模板加一个 CSV,每行生成一个渲染设计——适用于本地化帖子、个性化图形、证书或营销活动变体。为变量文本/图像节点标记 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 是连接两个节点的语义箭头。它没有手动指定的几何信息 — 只需提供 from 和 to 节点 ID,引擎便会在编译时根据目标节点解析后的边界框推导出两个端点。移动任一边界框后,连接器会自动重新路由;相同的源始终生成相同的路径。它是仅描边的叶节点(无填充、无子节点);要渲染它,必须指定 stroke 颜色。
- 端点锚定 —
from-anchor/to-anchor用于选择每一端的连接位置。简单流程图可使用命名网格锚点(top-left、bottom、center-right);需要在同一形状周围布置多个不同连线的精致图表,则可使用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 目录。完整的 Lucide 图标集(1745 个图标)已随附内置。
资源包会导出以 <package>#<item> 形式寻址的条目,通过 zenith library add 将其实例化到文档中。条目分为三种类型:component(节点组,以 instance 形式放置)、token(滤镜/蒙版令牌)和 action(预设事务)。
资源包采用以下两种格式之一:
.zen文件 — 功能丰富的格式:直接编写令牌、组件和操作。它通过library自身条目声明其身份。*.svg目录 — 即插即用格式,适用于图标集。每个*.svg都是一个图标,其 ID 为文件名(不含扩展名)。无需编写任何内容:将文件夹放入<project>/libraries/,它就会成为一个资源包,地址为@local/<dirname>#<stem>。
SVG 图标在添加时会转换为原生、可编辑的 path 节点,而不是作为不透明的光栅图嵌入,也不会使用 <image> 引用。可以像处理其他几何图形一样,使用实例覆盖样式(override ref="icon.0" stroke=(token)"brand" …)。转换是确定性的,且范围明确:添加一个图标,就只转换一个图标。
内置的 @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 会返回 house,而不是 lamp。查询中的每个词都必须匹配,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 的内置资源包。
命令概览
创作 · 渲染 · 编辑 · 变体 · 库 · 主题 · 历史记录 · Agent — 每个命令都支持 --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(浏览器编辑器和 Agent HTTP API,参见浏览器编辑器) |
| 变体 | variant(一个设计 → 多种尺寸/格式) · 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 |
| Agent | plugin install · plugin uninstall · plugin list · mcp |
在浏览器中编辑 .zen 文件:一侧显示源文本,另一侧显示渲染后的页面。可使用本地服务器或静态站点。
源文本窗格是内容的权威来源。画布显示引擎对该文本的渲染结果。在画布中进行的编辑(移动、调整大小、旋转、检查器字段)会转化为修改文本的事务。
zenith edit poster.zen
此命令会在本地端口上提供一个文档,打印包含本次运行专属令牌的 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 RNG 生成的 64 位十六进制字符,每次运行都会更新。每个
/api路由都需要Authorization: Bearer <token>。服务器不会在其他任何地方接受令牌。Cookie 会发送到127.0.0.1上的每个服务,因为 Cookie 不区分端口。 - 页面 URL。
http://127.0.0.1:PORT/#token=<token>。浏览器绝不会将片段发送给服务器或包含在Referer中。页面会读取令牌,将其从地址栏和历史记录中移除,并将其保存在内存和此标签页的sessionStorage中(因此重新加载页面也能正常工作)。页面文件本身是公开的,无需令牌。 - 启动浏览器。 令牌不会出现在启动命令行中,其他本地用户可能会读取命令行。服务器会在
$XDG_RUNTIME_DIR(或临时目录)中写入一个带随机名称的0600重定向文件,打开该文件,并在首次经过身份验证的请求后将其删除。如果沙盒浏览器无法读取该文件,请打开打印出的 URL。 - Host 和 Origin。
Host必须是localhost、IP 地址或--host名称,并且端口必须与绑定端口相同。否则服务器会返回 403edit.bad_host。DNS 重绑定页面会在此处失败。请求包含Origin时,其值必须为http://<Host>。跨站 fetch 会收到 403edit.bad_origin。服务器不发送 CORS 标头。POST 请求体必须是application/json。 - 限制。 读取请求体前会检查请求头和令牌。请求头必须在 5 秒内到达。每个连接由一个线程处理,同时最多处理 64 个连接(同一远程对端最多 16 个)。空闲客户端无法阻塞实际请求。
- 文件。 服务器只提供内嵌的页面文件。引擎只会读取文档所在目录(或
--root)下的文档、导入项、资源、数据和文本源。越出该目录的..和符号链接都会报错。两次读取不会受此限制。配置文件(最近的.zenith.kdl和$HOME/.config/zenith/config.kdl)及系统字体的读取方式与其他 CLI 命令相同。 - 写入。 保存时会保留注释、记录历史、像
tx --apply一样写入doc-id时间戳、将字节同步到磁盘,并以原子方式替换文件。只读文档打开时会显示警告。页面会禁用 Save,并说明如何使文件可写。
服务器会持续运行,直到收到 Ctrl-C 或 POST /api/shutdown。存在未保存的编辑时,关机请求会返回 409,除非请求体为 {"force": true}。对于干净会话,Ctrl-C、SIGTERM 和 SIGHUP 会立即停止服务并以退出代码 0 退出。存在未保存的编辑时,第一个信号不会停止服务:终端会显示文件名,页面会显示带有 Save 的横幅。第二个信号会丢弃编辑并以退出代码 130 退出。
使用编辑器
- 布局。 源码和画布并排显示(窄屏上则上下排列)。拖动分隔线,或聚焦分隔线后使用方向键,可调整大小。全屏按钮可展开任一面板。按 Escape 恢复原状。工具栏按钮可隐藏页面与图层面板、检查器和诊断面板。布局和主题(系统、浅色、深色)会按浏览器保存。
- 画布视图。
+和-缩放,0显示 100%,1适应页面大小。按住 Ctrl 或 Cmd 滚动滚轮,或使用捏合手势,可围绕指针缩放。使用滚轮、双指、按住 Space 并拖动,或中键可平移。画布仅以设备分辨率渲染可见区域。 - 选择。 单击节点即可选中。按住 Shift 单击可将其添加到选区。在空白画布上拖动可框选(Alt:仅选择完全位于框内的节点;Shift:添加到选区)。图层、源码光标和画布共享同一选区。
- 移动、调整大小和旋转。 拖动节点或其控制柄。按住 Shift 可锁定一个轴、保持纵横比,或以 15 度为步进旋转。按住 Ctrl 或 Cmd 可围绕中心调整大小,并在移动时跳过吸附。按住 Alt 可分离受令牌绑定的值或锚点。松开时应用编辑结果。幽灵轮廓和实时预览会跟随指针。
- 吸附。 磁铁按钮可切换是否吸附到其他节点和页面。
- 选中时的键盘操作。 画布获得焦点时这些按键才有效:先单击画布。方向键每次移动 1 px(Shift:10 px)。按住 Ctrl 或 Cmd 并使用方向键可调整大小。
[和]按 15 度为步进旋转。Delete 或 Backspace 可删除。Escape 可取消拖动或清除选区。未选中内容时,方向键可平移画布。 - 检查器。 显示选中的节点并编辑其字段,包括使用颜色令牌设置填充和描边。
- 快捷键。 按住 Ctrl 或 Cmd 并使用:
S保存,Z撤销,Shift+Z或Y重做,D复制选中内容,O打开文件(静态站点)。撤销和重做会将输入和画布编辑纳入同一历史记录。 - 诊断。 底部面板会列出错误、警告和提示。带有位置的行可跳转到源码中的对应位置。
- 保存和冲突。 保存会将文本写入磁盘。如果磁盘上的文件发生更改,未编辑的会话会重新加载该文件。存在未保存编辑的会话会显示冲突提示:重新加载将采用磁盘上的文本(撤销可恢复你的文本),覆盖则会写入编辑器中的文本。关闭含有未保存编辑的标签页前,浏览器会询问是否确认。
事实来源
- 源码面板中的输入绝不会被覆盖。引擎会将其他更改(画布、Agent、磁盘)合并到面板中,同时保留已输入的按键内容。
- 画布和检查器中的编辑会就地修改文本。注释和布局会保留。如果无法准确应用补丁,引擎会以规范形式重写文档,显示一条注释已移除的警告,撤销操作可恢复注释。当编辑位置的布局无法准确应用补丁时,就会发生这种情况,例如节点与其他文本位于同一行、内联的
{ ... }子块,或新建的顶层节点。移除节点时,也会删除其正上方的//注释行,页面会对此进行说明。 - 源码存在错误时,画布会保留最后一次有效渲染,并标注“正在显示上次有效预览”,诊断面板则会列出错误。
静态站点
编辑器也可以作为静态站点运行。引擎以 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 引擎。如果没有该 meta 标签,页面会请求一次/api/state。zenith edit会响应,页面随后使用它。 - 使用工具栏按钮打开
.zen文件或项目文件夹。文件夹会为文档提供其导入项和资源。Chromium 会将保存内容写回文件。其他浏览器通过<input type=file>读取,并通过下载保存。 - 除 Noto Sans Regular 和 Bold 之外的打包字体会按需从
fonts/加载。 ?doc=samples/<name>.zen可打开示例。默认值为samples/stack.zen。- 每次引擎调用都会将会话和项目文件发送到模块。请勿将大型图片放入项目文件夹。
- 在静态站点上保存文件不会将
doc-id写入文件。
Agent 和 MCP
Agent 驱动的会话与页面上显示的会话相同。通过 HTTP,POST /api/cmd 会运行编辑器命令({"command":"commands.list"} 可列出命令)。Agent 所做的编辑会实时显示在页面上。通过 MCP,六个工具可调用引擎。它们仅打开和保存 .zen 文件。读取根目录为文档所在目录(或 root)。除非服务器以 zenith mcp --root / 运行,否则拒绝将 / 作为读取根目录。服务器最多保留 16 个会话:新会话会逐出最近最少使用且没有未保存编辑的会话。
| 工具 | 用途 |
|---|---|
zenith_editor_open | 在编辑器会话中打开 .zen 文件。返回会话 ID。脏会话需要传入 discard=true 才能重新打开。 |
zenith_editor_command | 在会话上运行一条编辑器命令(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,让查看页面的人看到 Agent 的编辑。传入它打印出的 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)
历史记录分为两个层级。撤销/重做会在临时会话时间线上移动——快速、本地,适用于进行中的工作。命名版本是持久化的内容寻址检查点(SHA-256 +
DEFLATE),会一直保留,直到你将其删除;restore 可跳转到任意版本。sync 用于将引擎外部所做的编辑纳入历史记录,确保历史完整。历史记录尽力写入:如果无法写入,文件仍会保存——编辑绝不会因此受阻。
与编码 Agent 搭配使用
使用 zenith plugin install 为 Claude Code / Codex / OpenCode / Cursor / … 安装技能,并为远程服务/CI 安装 MCP 服务。
Zenith 附带一项技能,用于教会 AI 编码 Agent 如何使用 CLI——Agent 驱动的创作 → 验证 → 渲染 → 编辑循环、设计方案,以及 --help 无法涵盖的令牌/品牌规范。为你使用的 Agent 安装该技能:
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 会获得完整的文件夹技能(参考资料包、模板和主题);其他 Agent(Cursor、Windsurf、Aider、Zed、Gemini、Copilot、Continue、Kiro、 Antigravity)会获得一个独立的规则文件,其中链接回自文档化的 CLI。匹配的文件会保持不变。使用以下命令升级已安装的资源:
zenith plugin install --force
--force 会覆盖存在差异的已安装文件,包括用户所做的更改。不加此参数时,存在差异的文件会保持不变。使用 zenith plugin uninstall 移除安装内容。
MCP 服务(远程 / CI / 托管 Agent)
对于通过模型上下文协议发现功能的 Agent,以及 CI 和托管/SaaS 流水线,Zenith 可作为一流的 MCP 服务运行。它并非对 CLI 的简单封装:工具结果经过精简,为结构化 JSON;通过单个 zenith_schema 工具按需获取架构详情(因此模型无需携带每种节点/操作的架构);大型或二进制产物(渲染结果、大型树、差异)会以指向内容寻址存储的资源链接形式返回,而非内联;文档可通过 doc-id 寻址,Agent 无需再管理路径。完整的创作循环均已开放——zenith_schema、zenith_validate、
zenith_inspect、zenith_tokens、zenith_tx、zenith_fix、zenith_render、zenith_perceive、zenith_fmt、zenith_merge、
zenith_theme_new,以及 scratch/candidate/promote/finalize 工作区工具。指针式编辑(命中测试、拖动、撤销、实时渲染)使用 zenith_editor_* 工具,详见浏览器编辑器。
| MCP 渲染参数 | 约定 |
|---|---|
format | 必填:png、svg、pdf 或 scene。 |
page | 从 1 开始。默认为所有 PDF 页面;其他格式默认为第 1 页。 |
raster_scale | SVG/PDF 的回退分辨率。有限值 0 < F <= 4,默认值为 1。 |
scale / contact_sheet | 仅适用于 PNG。 |
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 可在隔离式 / 托管式部署中更改其位置。
本地 Agent 应优先使用 CLI + 技能,而不是 MCP。如果环境可以运行二进制文件,直接运行
zenith(通过zenith plugin install安装)是最快的方式。只有在无法运行二进制文件时才使用 MCP 服务——例如远程主机、CI、沙盒或托管式 / 生产服务,在这些场景中,你需要通过协议提供完整的读写能力。MCP 服务在这些场景中是首选方案。
此代码仓库提供了 server.json(MCP 注册表清单)。手动触发
Publish MCP 工作流,可为选定的稳定标签发布相应的 npm 启动器和注册表条目(通过 GitHub OIDC——无需注册表令牌),让 Zenith 能在 MCP 目录中保持可发现,并可由客户端通过 npx -y @zenitheditor/zenith-mcp 启动。
- MCP 注册表名称:
mcp-name: io.github.zenitheditor/zenith
由各司其职的 Rust crate 组成的工作区;zenith-geometry 不依赖其他 Zenith crate。
每个 crate 负责一项工作,并提供稳定的契约。zenith-geometry 不依赖其他 Zenith crate。zenith-core 在这些 crate 中只依赖 zenith-geometry。
| Crate | 职责 |
|---|---|
zenith-geometry | 纯几何:路径、轮廓、布尔运算 |
zenith-core | KDL 解析器适配器、语义 AST、规范化格式化器、保留注释的源文件补丁器、令牌、验证、诊断 |
zenith-layout | 文本整形与字体度量(rustybuzz + ttf-parser);第三方类型仅限在此使用 |
zenith-raster | 光栅表面、混合模式、调整 |
zenith-perception | 针对几何和光栅的视觉 QA 报告 |
zenith-scene | 与后端无关的场景 IR + 编译(几何、文本换行、锚点、不透明度/裁剪、命中数据) |
zenith-render | CPU PNG 后端(tiny-skia)、SVG 导出和矢量 PDF 后端;强制确定性 |
zenith-tx | 事务操作集、应用/试运行引擎、差异和审计记录契约 |
zenith-session | 本地机器上的文档身份、会话 DAG、持久化版本(内容寻址存储) |
zenith-zpx | 打包设计导出(清单 + 烘焙) |
zenith-producers | 更高层级的生成/导出辅助工具(原生 SVG、ZPX 烘焙) |
zenith-pipeline | 配置策略、导入、字体、资源、验证、编译,以及通过主机 I/O trait 执行渲染;由 CLI 和 wasm 编辑器共用 |
zenith-editor | 编辑器引擎:在可序列化会话上运行的无状态命令注册表;由浏览器、zenith edit 和 MCP 共用 |
zenith-editor-wasm | 作为 wasm32-wasip1 命令模块的编辑器引擎,用于静态网站(不发布) |
zenith-cli | zenith 命令行工具(crate zenith-tool):分发、参数解析、JSON/人类可读输出、MCP |
在你的代码库中使用
`.zen` 文件只是文本——提交它,在 PR 中审查它,在 CI 中渲染它,并回滚它。
Zenith 文件只是文本,因此可以和代码放在一起。将它提交到 git。在 pull request 中并排查看差异,审查设计变更。在 CI 中渲染,及时发现上线前的布局问题。在工作流中生成多个变体。像回滚其他文件一样回滚它。设计不再是一个需要导入导出的独立世界,而是构建流程的一部分。
适用对象
AI/Agent 构建者、工程团队、大批量内容制作方和工具构建者。
- AI 和 Agent 构建者:需要可靠地生成和编辑视觉内容,而不是靠截图碰运气。
- 工程团队:希望将设计资源放入代码库,在 PR 中审查,并在 CI 中构建。
- 大批量内容制作方——营销、出版、本地化:需要大量正确的变体。
- 工具构建者:更愿意基于开放格式构建,而不是依赖封闭的云 API。
可重复使用的 Zenith 示例位于 zenith-showcase 子模块中。
公开展示库位于 zenitheditor/zenith-showcase,并在此作为 zenith-showcase 子模块链接。
这里汇集了可重复使用的 Zenith 示例:.zen 源文件、渲染输出、视觉方案、动作、滤镜、背景、海报、传单、书籍、杂志、广告、图表、演示文稿以及其他生成式设计作品。
只有在你拥有分享文件的权利,并且允许他人依据声明的许可证重复使用所提交的源文件、输出和资源时,才将文件放入展示库。私人作品、客户作品、仅用于作品集的作品或采用自定义许可证的作品,应改为链接到展示库的外部作品集;外部作品的许可仍由所有者决定。
状态
Zenith 正处于首个公开发布系列。作者 → 验证 → 编辑 → 渲染的流程已端到端打通:解析、诊断集、事务引擎、PNG/SVG/PDF 渲染、本地历史记录、库子系统和变量数据合并均已实现并通过测试。随着项目逐步成熟,格式、线缆类型和命令接口仍可能演变。
贡献
有关如何参与引擎开发,请参阅 CONTRIBUTING.md;有关具有约束力的仓库约定(人类贡献者和 Agent 贡献者均以此为准),请参阅 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)。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。