archify

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Archify Skill

Archify 技能

Create professional technical diagrams as self-contained HTML files with inline SVG, a theme toggle, and a built-in image/SVG export menu.
Every diagram ships with a dark/light theme toggle (persists in
localStorage
, respects
prefers-color-scheme
), an export menu (copy PNG to clipboard; download PNG/JPEG/WebP rasterized natively at up to 4× resolution; download a dual-theme SVG that follows the embedding host's
prefers-color-scheme
— ideal for GitHub READMEs), and a CSS-variable color system that keeps both themes consistent.
创建包含内嵌SVG、主题切换功能和内置图片/SVG导出菜单的独立HTML文件形式的专业技术图表。
每个图表都配备明暗主题切换器(状态存储在
localStorage
中,遵循
prefers-color-scheme
设置)、导出菜单(将PNG复制到剪贴板;以最高4倍分辨率原生下载PNG/JPEG/WebP格式的栅格图;下载适配嵌入宿主
prefers-color-scheme
双主题SVG——非常适合GitHub README),以及确保双主题风格一致的CSS变量配色系统

Setup (one-time, renderer modes only)

初始化设置(仅渲染器模式需执行一次)

The five typed renderers validate JSON against schemas via
ajv
. From this skill's folder:
bash
npm install
Without it the renderers still run — they print a warning and skip schema validation, keeping their own layout checks. The generated HTML never has dependencies; only the renderers do.
If you have no shell access at all (e.g. the skill was added as project knowledge), fall back to architecture mode for every request: hand-place SVG into
assets/template.html
following the Design System below, and run the self-review checklist before delivering.
五种类型的渲染器通过
ajv
验证JSON与Schema的一致性。在本技能所在文件夹下执行:
bash
npm install
即使不执行该命令,渲染器仍可运行——此时会打印警告并跳过Schema验证,仅保留自身的布局检查。生成的HTML文件完全无依赖;仅渲染器存在依赖。
若完全无法访问命令行(例如该技能作为项目知识添加),则所有请求均采用架构模式:按照下方设计系统将SVG手动放入
assets/template.html
,并在交付前运行自我检查清单。

Choosing a Diagram Type

选择图表类型

TypeUse forHow
architecture
System components, cloud resources, services, security boundaries, infrastructure
renderers/architecture/render-architecture.mjs
+ JSON (or hand-place SVG when renderers can't run)
workflow
Technical flows, approval gates, tool calls, runbooks, CI/CD, incident response
renderers/workflow/render-workflow.mjs
+ JSON
sequence
API call chains, request lifecycles, cache fallback, async traces, return paths
renderers/sequence/render-sequence.mjs
+ JSON
dataflow
Pipelines, ETL/ELT, PII isolation, lineage, warehouse sync, consumers
renderers/dataflow/render-dataflow.mjs
+ JSON
lifecycle
State machines, status transitions, wait states, retries, terminal states
renderers/lifecycle/render-lifecycle.mjs
+ JSON
Trigger phrases: "architecture/system/cloud diagram" →
architecture
(unless clearly process-oriented). "workflow/flow/process/runbook/approval/CI-CD/incident" →
workflow
. "sequence/interaction/call chain/who calls whom" →
sequence
. "data flow/pipeline/ETL/lineage/PII/governance" →
dataflow
. "state/status/lifecycle/state machine/retry/terminal" →
lifecycle
.
类型适用场景实现方式
architecture
系统组件、云资源、服务、安全边界、基础设施
renderers/architecture/render-architecture.mjs
+ JSON(当渲染器无法运行时手动放置SVG)
workflow
技术流程、审批关卡、工具调用、运行手册、CI/CD、事件响应
renderers/workflow/render-workflow.mjs
+ JSON
sequence
API调用链、请求生命周期、缓存回退、异步追踪、返回路径
renderers/sequence/render-sequence.mjs
+ JSON
dataflow
数据管道、ETL/ELT、PII隔离、数据血缘、仓库同步、数据消费
renderers/dataflow/render-dataflow.mjs
+ JSON
lifecycle
状态机、状态转换、等待状态、重试、终止状态
renderers/lifecycle/render-lifecycle.mjs
+ JSON
触发短语:"架构/系统/云图" →
architecture
(除非明确为流程导向)。"工作流/流程/过程/运行手册/审批/CI-CD/事件" →
workflow
。"序列/交互/调用链/谁调用谁" →
sequence
。"数据流/管道/ETL/数据血缘/PII/治理" →
dataflow
。"状态/状态机/生命周期/重试/终止" →
lifecycle

Mermaid as an Input Dialect

Mermaid作为输入格式

When the user pastes Mermaid code, do NOT try to render or parse it mechanically — read it for structure and lay out from scratch in the matching archify mode:
MermaidArchify modeMapping
flowchart
/
graph
workflow
(or
architecture
if it's a component map)
subgraph
→ lane or region boundary; node shape
{}
(diamond) → decision/security node;
-->
labels → edge labels (use sparingly);
classDef
/
style
→ nearest semantic type
sequenceDiagram
sequence
participant
→ participants (pick semantic
type
from the name);
->>
→ message,
-->>
return
variant;
Note
→ message
note
;
rect
blocks → segments
stateDiagram
lifecycle
states → states (pick
start
/
active
/
waiting
/
success
/
failure
from names);
[*]
start/end →
start
type /
terminal
lane; transition labels → event-like labels
Drop Mermaid styling; keep only the topology and meaning. You choose grouping, lane order, and what deserves emphasis — that judgment is the product.
当用户粘贴Mermaid代码时,请勿尝试机械渲染或解析——先读取其结构,然后以匹配的Archify模式从头布局
Mermaid类型Archify模式映射规则
flowchart
/
graph
workflow
(若为组件图则用
architecture
subgraph
→ 泳道或区域边界;节点形状
{}
(菱形)→ 决策/安全节点;
-->
标签 → 边标签(慎用);
classDef
/
style
→ 最接近的语义类型
sequenceDiagram
sequence
participant
→ 参与者(从名称中选择语义
type
);
->>
→ 消息,
-->>
→ 返回变体;
Note
→ 消息
note
rect
块 → 分段
stateDiagram
lifecycle
状态 → 状态(从名称中选择
start
/
active
/
waiting
/
success
/
failure
);
[*]
开始/结束 →
start
类型 /
terminal
泳道;转换标签 → 类事件标签
丢弃Mermaid的样式;仅保留拓扑结构和核心含义。分组方式、泳道顺序以及重点内容由你决定——这种判断是本工具的核心价值。

Layout principles (read before placing)

布局原则(放置前必读)

Archify's readability comes from spatial narrative, not from drawing every dependency as an arrow. Before you write coordinates or edge lists, plan one clear story:
  1. One main path — left → right (architecture) or lane → column (workflow). The reader should trace the happy path without crossing lines.
  2. Few labeled edges — label only cross-boundary or non-obvious transitions on the main path. Adjacent steps stay unlabeled.
  3. Short side branches — permissions, storage, bots, CI: connect up or down from the nearest node on the main path. Never route a secondary edge diagonally across unrelated components.
  4. Cards for detail — policies, tech stack notes, and "also connects to X" belong in summary cards, not as extra arrows.
  5. Mode fit — process / approval / tool-call stories →
    workflow
    or
    sequence
    . Component maps with ≤12 nodes →
    architecture
    . If the diagram needs 20+ edges, remove edges until the main path is obvious.
Worked examples on this pattern:
examples/archify-repo.architecture.json
(this repo) and
examples/maka-architecture.architecture.json
(third-party desktop app).
When validation fails on label overlap, read the Suggested fix lines (coordinates /
labelAt
/
labelDy
) and apply them directly — do not guess offsets blindly.
Archify的可读性源于空间叙事,而非绘制每一个依赖箭头。在编写坐标或边列表之前,先规划一条清晰的主线:
  1. 单一主路径 —— 从左到右(架构图)或泳道到列(工作流图)。读者应能无需交叉线条即可追踪正常流程。
  2. 少量带标签的边 —— 仅为主路径上跨边界或非显式转换添加标签。相邻步骤保持无标签。
  3. 简短分支 —— 权限、存储、机器人、CI:从主路径上最近的节点向上或向下连接。切勿让次要边斜跨无关组件。
  4. 卡片承载细节 —— 策略、技术栈说明以及"还连接到X"等内容应放在摘要卡片中,而非添加额外箭头。
  5. 模式匹配 —— 流程/审批/工具调用类场景 →
    workflow
    sequence
    。节点数≤12的组件图 →
    architecture
    。若图表需要20+条边,则删除边直到主路径清晰可见。
该模式的示例:
examples/archify-repo.architecture.json
(本仓库)和
examples/maka-architecture.architecture.json
(第三方桌面应用)。
当验证因标签重叠失败时,直接参考建议修复行(坐标/
labelAt
/
labelDy
)进行调整——切勿盲目猜测偏移量。

Renderer Modes (architecture / workflow / sequence / dataflow / lifecycle)

渲染器模式(architecture / workflow / sequence / dataflow / lifecycle)

All five modes follow the same loop:
  1. Read first: the schema (
    schemas/<type>.schema.json
    ) and the complete worked example (
    examples/*.{architecture,workflow,sequence,dataflow,lifecycle}.json
    ) — copy its patterns instead of guessing field shapes.
  2. Write
    <name>.<type>.json
    .
  3. Render:
    node bin/archify.mjs render <type> <input>.json <output>.html
    (paths relative to this skill's folder).
  4. Validate the generated artifact:
    node bin/archify.mjs validate <type> <input>.json --json
    , or check an existing HTML file with
    node bin/archify.mjs check <output>.html
    . This catches malformed SVG output, non-finite SVG values, two-point diagonal arrows, and arrows crossing the legend.
  5. If either step fails, the error names the JSON path or the fix (thresholds, valid ranges, which knob to change). Fix the JSON and re-run; never edit the renderer.
Schema violations exit non-zero with path-prefixed messages like
/nodes/3 (id/label: "router") must NOT have additional properties
. The renderers additionally fail fast on layout problems: node/state overlap (including cross-lane), labels colliding with nodes or other labels, labels wider than their node, out-of-range columns/rows, too-short edges, workflow edges crossing unrelated nodes, and legends outside the viewBox. CJK text is measured at double width automatically.
Set
meta.animation: "trace"
only when the user asks for motion or a presentation/demo view. It adds lightweight SVG/CSS trace animation to renderer-marked arrows and nodes, respects
prefers-reduced-motion
, and leaves the default static output unchanged.
五种模式遵循相同流程:
  1. 先阅读:Schema文件(
    schemas/<type>.schema.json
    )和完整示例(
    examples/*.{architecture,workflow,sequence,dataflow,lifecycle}.json
    )——复制其模式而非猜测字段格式。
  2. 编写
    <name>.<type>.json
    文件。
  3. 渲染:
    node bin/archify.mjs render <type> <input>.json <output>.html
    (路径相对于本技能所在文件夹)。
  4. 验证生成的产物:
    node bin/archify.mjs validate <type> <input>.json --json
    ,或用
    node bin/archify.mjs check <output>.html
    检查现有HTML文件。这会捕获格式错误的SVG输出、非有限SVG值、两点对角线箭头以及穿过图例的箭头。
  5. 若任一步骤失败,错误信息会指出JSON路径或修复方案(阈值、有效范围、需调整的参数)。修复JSON后重新运行;切勿编辑渲染器。
Schema违规会以非零状态退出,并显示带路径前缀的消息,例如
/nodes/3 (id/label: "router") must NOT have additional properties
。渲染器还会快速检测布局问题:节点/状态重叠(包括跨泳道)、标签与节点或其他标签碰撞、标签宽于节点、列/行超出范围、边过短、工作流边跨无关节点、图例超出 viewBox。CJK文本会自动按双倍宽度计算。
仅当用户要求动态效果或演示视图时,设置
meta.animation: "trace"
。它会为渲染器标记的箭头和节点添加轻量SVG/CSS追踪动画,遵循
prefers-reduced-motion
设置,且不改变默认静态输出。

Workflow

Workflow(工作流)

json
{
  "schema_version": 1,
  "diagram_type": "workflow",
  "meta": { "title": "Release Workflow", "subtitle": "PR to production", "output": "release.html" },
  "lanes": [ { "id": "dev", "label": "Developer" }, { "id": "ci", "label": "CI" }, { "id": "exceptions", "label": "Exception Handling", "variant": "exception" } ],
  "phases": [ { "id": "intake", "label": "Intake", "fromCol": 0, "toCol": 1 } ],
  "groups": [ { "id": "checks", "label": "Parallel checks", "lane": "ci", "fromCol": 1, "toCol": 3, "variant": "emphasis" } ],
  "mainPath": ["pr", "build"],
  "nodes": [
    { "id": "pr", "lane": "dev", "col": 0, "type": "frontend", "label": "Open PR", "sublabel": "feature branch" },
    { "id": "build", "lane": "ci", "col": 1, "type": "backend", "label": "Build", "sublabel": "lint + test", "tag": "blocking" }
  ],
  "edges": [
    { "from": "pr", "to": "build", "label": "webhook", "variant": "emphasis", "fromSide": "bottom", "toSide": "top", "route": "drop" }
  ],
  "cards": []
}
Layout budget: 6 columns (
col
0–5) at fixed x positions
[88, 220, 300, 430, 500, 625]
— columns 1↔2 and 3↔4 are only 70–80px apart, so default-width (92px) nodes in those adjacent columns of the same lane overlap; skip a column or shrink
width
. Lane content width is 640px. Omit
meta.viewBox
— the renderer sizes height to the lane count automatically. Use
phases
for top-of-diagram story beats,
groups
to frame parallel work or a branch inside one lane, and
lane.variant: "exception"
for error/retry/fallback lanes.
mainPath
is optional but recommended: list the happy-path node ids in order so the renderer can catch missing edges or accidental backward movement. Edge routes:
straight
,
drop
(bend between lanes;
bias
0–1 picks where),
outside-right
,
return-left
,
bottom-channel
,
up-channel
, or explicit
via
points. Keep adjacent-step edges unlabeled; reserve labels for cross-lane transitions, approvals, async traces, and returns.
json
{
  "schema_version": 1,
  "diagram_type": "workflow",
  "meta": { "title": "Release Workflow", "subtitle": "PR to production", "output": "release.html" },
  "lanes": [ { "id": "dev", "label": "Developer" }, { "id": "ci", "label": "CI" }, { "id": "exceptions", "label": "Exception Handling", "variant": "exception" } ],
  "phases": [ { "id": "intake", "label": "Intake", "fromCol": 0, "toCol": 1 } ],
  "groups": [ { "id": "checks", "label": "Parallel checks", "lane": "ci", "fromCol": 1, "toCol": 3, "variant": "emphasis" } ],
  "mainPath": ["pr", "build"],
  "nodes": [
    { "id": "pr", "lane": "dev", "col": 0, "type": "frontend", "label": "Open PR", "sublabel": "feature branch" },
    { "id": "build", "lane": "ci", "col": 1, "type": "backend", "label": "Build", "sublabel": "lint + test", "tag": "blocking" }
  ],
  "edges": [
    { "from": "pr", "to": "build", "label": "webhook", "variant": "emphasis", "fromSide": "bottom", "toSide": "top", "route": "drop" }
  ],
  "cards": []
}
布局限制:6列(
col
0–5),固定X坐标为
[88, 220, 300, 430, 500, 625]
——同一泳道中相邻的1↔2列和3↔4列间距仅70–80px,默认宽度(92px)的节点会重叠;需跳过一列或缩小
width
。泳道内容宽度为640px。无需设置
meta.viewBox
——渲染器会根据泳道数量自动调整高度。使用
phases
定义图表顶部的阶段节点,
groups
在单个泳道中框选并行工作或分支,
lane.variant: "exception"
用于错误/重试/回退泳道。
mainPath
可选但推荐:按顺序列出正常流程的节点ID,以便渲染器检测缺失的边或意外的反向移动。边路由方式:
straight
drop
(泳道间弯曲;
bias
0–1选择弯曲位置)、
outside-right
return-left
bottom-channel
up-channel
或显式
via
点。相邻步骤的边保持无标签;仅为跨泳道转换、审批、异步追踪和返回添加标签。

Sequence

Sequence(序列)

json
{
  "schema_version": 1,
  "diagram_type": "sequence",
  "meta": { "title": "Cache Miss Request", "subtitle": "auth and cache fallback", "output": "cache-miss.html" },
  "participants": [
    { "id": "web", "type": "frontend", "label": "Web App", "sublabel": "React UI" },
    { "id": "api", "type": "backend", "label": "API", "sublabel": "handler" }
  ],
  "segments": [ { "from": 160, "to": 320, "label": "01 / AUTH" } ],
  "messages": [
    { "from": "web", "to": "api", "y": 200, "label": "GET /data", "variant": "emphasis" },
    { "from": "api", "to": "web", "y": 290, "label": "200 JSON", "variant": "return" }
  ],
  "activations": [ { "participant": "api", "from": 190, "to": 300, "type": "backend" } ],
  "cards": []
}
Layout budget: participants sit at x = 62 + index×108, so a 920-wide viewBox fits at most 8. Message
y
must stay within
[160, viewBox_height − 83]
; messages that share horizontal space need ≥28px vertical separation; arrows need ≥60px horizontal span.
segments[].from/to
and
activations[].from/to
are y pixel coordinates, not participant ids. A taller
meta.viewBox
(default
[920, 760]
) buys more timeline room. Keep labels short: "GET /path", "verify JWT", "cache miss", "200 JSON".
json
{
  "schema_version": 1,
  "diagram_type": "sequence",
  "meta": { "title": "Cache Miss Request", "subtitle": "auth and cache fallback", "output": "cache-miss.html" },
  "participants": [
    { "id": "web", "type": "frontend", "label": "Web App", "sublabel": "React UI" },
    { "id": "api", "type": "backend", "label": "API", "sublabel": "handler" }
  ],
  "segments": [ { "from": 160, "to": 320, "label": "01 / AUTH" } ],
  "messages": [
    { "from": "web", "to": "api", "y": 200, "label": "GET /data", "variant": "emphasis" },
    { "from": "api", "to": "web", "y": 290, "label": "200 JSON", "variant": "return" }
  ],
  "activations": [ { "participant": "api", "from": 190, "to": 300, "type": "backend" } ],
  "cards": []
}
布局限制:参与者位于x = 62 + index×108的位置,因此920宽的viewBox最多容纳8个参与者。消息
y
必须在
[160, viewBox_height − 83]
范围内;共享水平空间的消息需保持≥28px的垂直间距;箭头需≥60px的水平跨度。
segments[].from/to
activations[].from/to
Y像素坐标,而非参与者ID。更大的
meta.viewBox
(默认
[920, 760]
)可提供更多时间轴空间。标签保持简短:"GET /path"、"verify JWT"、"cache miss"、"200 JSON"。

Dataflow

Dataflow(数据流)

json
{
  "schema_version": 1,
  "diagram_type": "dataflow",
  "meta": { "title": "Product Analytics", "subtitle": "events to consumers", "output": "analytics.html" },
  "stages": [ { "label": "Sources" }, { "label": "Ingest" }, { "label": "Store" } ],
  "nodes": [
    { "id": "web", "type": "frontend", "label": "Web App", "stage": 0, "row": 0, "sublabel": "clickstream" },
    { "id": "kafka", "type": "messagebus", "label": "Kafka", "stage": 1, "row": 0, "tag": "accepted events" }
  ],
  "flows": [
    { "from": "web", "to": "kafka", "label": "events", "classification": "PII touch", "variant": "emphasis" }
  ],
  "cards": []
}
Layout budget: 2–5 stages at x = 100 + stage×215; 5 rows (
row
0–4) at y
[128, 242, 356, 470, 584]
; default node 112×58. Default viewBox
[940, 720]
. Flow labels are mandatory and asset-like ("clickstream", "identity map", "feature vectors"); put sensitivity in
classification
("PII touch", "approved only", "non-PII"). Variants:
emphasis
= primary path,
security
= PII/policy/consent,
dashed
= async/batch.
json
{
  "schema_version": 1,
  "diagram_type": "dataflow",
  "meta": { "title": "Product Analytics", "subtitle": "events to consumers", "output": "analytics.html" },
  "stages": [ { "label": "Sources" }, { "label": "Ingest" }, { "label": "Store" } ],
  "nodes": [
    { "id": "web", "type": "frontend", "label": "Web App", "stage": 0, "row": 0, "sublabel": "clickstream" },
    { "id": "kafka", "type": "messagebus", "label": "Kafka", "stage": 1, "row": 0, "tag": "accepted events" }
  ],
  "flows": [
    { "from": "web", "to": "kafka", "label": "events", "classification": "PII touch", "variant": "emphasis" }
  ],
  "cards": []
}
布局限制:2–5个阶段,x = 100 + stage×215;5行(
row
0–4),y坐标为
[128, 242, 356, 470, 584]
;默认节点尺寸112×58。默认viewBox为
[940, 720]
。流标签为必填项,且需体现资产属性("clickstream"、"identity map"、"feature vectors");敏感性信息放在
classification
中("PII touch"、"approved only"、"non-PII")。变体:
emphasis
= 主路径,
security
= PII/政策/授权,
dashed
= 异步/批量。

Lifecycle

Lifecycle(生命周期)

json
{
  "schema_version": 1,
  "diagram_type": "lifecycle",
  "meta": { "title": "Agent Run Lifecycle", "subtitle": "states and terminal outcomes", "output": "agent-run.html" },
  "lanes": [
    { "id": "main", "label": "Lifecycle phases" },
    { "id": "waiting", "label": "Interruptions" },
    { "id": "terminal", "label": "Terminal exits" }
  ],
  "states": [
    { "id": "queued", "type": "start", "label": "Queued", "lane": "main", "col": 0, "step": "01" },
    { "id": "running", "type": "active", "label": "Executing", "lane": "main", "col": 2, "step": "02" },
    { "id": "approval", "type": "waiting", "label": "Needs Approval", "lane": "waiting", "col": 0 },
    { "id": "done", "type": "success", "label": "Completed", "lane": "terminal", "col": 2 }
  ],
  "transitions": [
    { "from": "queued", "to": "running", "variant": "emphasis" },
    { "from": "running", "to": "approval", "label": "needs approval", "variant": "security", "fromSide": "bottom", "toSide": "right" },
    { "from": "running", "to": "done", "label": "success", "variant": "emphasis", "fromSide": "bottom", "toSide": "top" }
  ],
  "cards": []
}
Layout budget — lane ids are semantic and reserved:
main
is required and maps to the top phase band (cols 0–4);
terminal
maps to the bottom outcome band (cols 0–2); every other lane id shares the single middle event band (cols 0–2) — separate same-band states with different
col
or
yOffset
. Band headers render from your lane labels. Default viewBox
[980, 660]
. Keep transition labels event-like and sparse ("retry", "timeout", "cancel"); prefer state
tag
s,
step
numbers, and summary cards over label-heavy arrows. Put terminal states in the
terminal
lane so endings are unambiguous.
json
{
  "schema_version": 1,
  "diagram_type": "lifecycle",
  "meta": { "title": "Agent Run Lifecycle", "subtitle": "states and terminal outcomes", "output": "agent-run.html" },
  "lanes": [
    { "id": "main", "label": "Lifecycle phases" },
    { "id": "waiting", "label": "Interruptions" },
    { "id": "terminal", "label": "Terminal exits" }
  ],
  "states": [
    { "id": "queued", "type": "start", "label": "Queued", "lane": "main", "col": 0, "step": "01" },
    { "id": "running", "type": "active", "label": "Executing", "lane": "main", "col": 2, "step": "02" },
    { "id": "approval", "type": "waiting", "label": "Needs Approval", "lane": "waiting", "col": 0 },
    { "id": "done", "type": "success", "label": "Completed", "lane": "terminal", "col": 2 }
  ],
  "transitions": [
    { "from": "queued", "to": "running", "variant": "emphasis" },
    { "from": "running", "to": "approval", "label": "needs approval", "variant": "security", "fromSide": "bottom", "toSide": "right" },
    { "from": "running", "to": "done", "label": "success", "variant": "emphasis", "fromSide": "bottom", "toSide": "top" }
  ],
  "cards": []
}
布局限制——泳道ID为语义化预留值
main
为必填项,对应顶部阶段带(列0–4);
terminal
对应底部结果带(列0–2);其他所有泳道ID共享中间事件带(列0–2)——同一带中的状态通过不同
col
yOffset
区分。带标题从泳道标签生成。默认viewBox为
[980, 660]
。转换标签保持类事件风格且尽量精简("retry"、"timeout"、"cancel");优先使用状态
tag
step
编号和摘要卡片,而非带大量标签的箭头。将终止状态放在
terminal
泳道中,确保结束状态清晰明确。

Per-mode deep guidance

各模式深度指南

Each renderer has a README with its full design language (route presets, semantic types, story guidance):
renderers/workflow/README.md
,
renderers/sequence/README.md
,
renderers/dataflow/README.md
,
renderers/lifecycle/README.md
. Read the matching one before your first diagram of that mode in a session.
每个渲染器都有包含完整设计语言(路由预设、语义类型、叙事指南)的README文件:
renderers/workflow/README.md
renderers/sequence/README.md
renderers/dataflow/README.md
renderers/lifecycle/README.md
。在会话中首次创建某类图表前,先阅读对应README。

Architecture Mode

Architecture模式(架构)

Architecture has the same read-schema-then-render loop as the other modes — prefer it. Hand-placed SVG is the fallback for when renderers can't run.
json
{
  "schema_version": 1,
  "diagram_type": "architecture",
  "meta": { "title": "Sample Web App", "subtitle": "3-tier SaaS on AWS", "output": "web-app.html" },
  "components": [
    { "id": "users", "type": "external", "label": "Users", "sublabel": "Browser", "pos": [40, 300] },
    { "id": "api", "type": "backend", "label": "API Server", "sublabel": "FastAPI :8000", "pos": [460, 300] },
    { "id": "db", "type": "database", "label": "PostgreSQL", "sublabel": ":5432", "pos": [680, 300] }
  ],
  "boundaries": [
    { "kind": "region", "label": "AWS us-west-2", "wraps": ["api", "db"] }
  ],
  "connections": [
    { "from": "users", "to": "api", "label": "HTTPS", "variant": "emphasis" },
    { "from": "api", "to": "db", "label": "SQL" }
  ],
  "cards": []
}
Render:
node bin/archify.mjs render architecture <input>.json <output>.html
.
Free placement
pos: [x, y]
is the component's top-left;
size: [w, h]
defaults to
[120, 60]
. Unlike typed modes there is no lane/stage grid — asymmetric placement is yours to choose.
meta.viewBox
is optional (auto-fitted).
Grid placement (#8) — when manual coordinates are painful, set semantic cells instead of doing arithmetic:
json
{
  "layout": { "mode": "grid", "cols": 7, "origin": [40, 100], "gapX": 24, "gapY": 48, "cellW": 120, "cellH": 60 },
  "components": [
    { "id": "agents", "type": "frontend", "label": "Agent Hosts", "row": 1, "col": 1 },
    { "id": "ir", "type": "messagebus", "label": "JSON IR", "row": 1, "col": 2 }
  ]
}
pos
still wins when present (override one cell). This is not auto-layout — spacing is fixed cell math. Example:
examples/archify-repo-grid.architecture.json
.
Inspect layout (#9) — after editing JSON, dump computed boxes without opening HTML:
bash
node bin/archify.mjs inspect architecture my.architecture.json
架构模式与其他模式遵循相同的"先读Schema再渲染"流程——优先使用该模式。手动放置SVG是渲染器无法运行时的备选方案。
json
{
  "schema_version": 1,
  "diagram_type": "architecture",
  "meta": { "title": "Sample Web App", "subtitle": "3-tier SaaS on AWS", "output": "web-app.html" },
  "components": [
    { "id": "users", "type": "external", "label": "Users", "sublabel": "Browser", "pos": [40, 300] },
    { "id": "api", "type": "backend", "label": "API Server", "sublabel": "FastAPI :8000", "pos": [460, 300] },
    { "id": "db", "type": "database", "label": "PostgreSQL", "sublabel": ":5432", "pos": [680, 300] }
  ],
  "boundaries": [
    { "kind": "region", "label": "AWS us-west-2", "wraps": ["api", "db"] }
  ],
  "connections": [
    { "from": "users", "to": "api", "label": "HTTPS", "variant": "emphasis" },
    { "from": "api", "to": "db", "label": "SQL" }
  ],
  "cards": []
}
渲染命令:
node bin/archify.mjs render architecture <input>.json <output>.html
自由布局 ——
pos: [x, y]
为组件左上角坐标;
size: [w, h]
默认值为
[120, 60]
。与类型化模式不同,此处无泳道/阶段网格——可自由选择非对称布局。
meta.viewBox
为可选(自动适配)。
网格布局(#8) —— 当手动计算坐标繁琐时,使用语义化单元格替代算术计算:
json
{
  "layout": { "mode": "grid", "cols": 7, "origin": [40, 100], "gapX": 24, "gapY": 48, "cellW": 120, "cellH": 60 },
  "components": [
    { "id": "agents", "type": "frontend", "label": "Agent Hosts", "row": 1, "col": 1 },
    { "id": "ir", "type": "messagebus", "label": "JSON IR", "row": 1, "col": 2 }
  ]
}
若存在
pos
则优先使用(覆盖单个单元格)。这并非自动布局——间距为固定单元格计算结果。示例:
examples/archify-repo-grid.architecture.json
检查布局(#9) —— 编辑JSON后,无需打开HTML即可导出计算后的盒模型:
bash
node bin/archify.mjs inspect architecture my.architecture.json

or: node bin/archify.mjs validate architecture my.architecture.json --layout-json

或:node bin/archify.mjs validate architecture my.architecture.json --layout-json


Output includes component rects, boundaries, connection point paths, and label positions.

**The renderer does the mechanical work that used to be hand-tuned**, so you only choose coordinates and meaning:

- **Free coordinates** — `pos: [x, y]` is the component's top-left; `size: [w, h]` defaults to `[120, 60]`. Unlike the typed modes there is no lane/stage grid — asymmetric placement is yours to choose. `meta.viewBox` is optional (auto-fitted to your components + a legend row).
- **Grid placement** — optional `layout.mode: "grid"` with `row`/`col` per component (see above). Not dagre; fixed cell spacing only.
- **Boundaries from `wraps`** — list the component ids a `region` (dashed amber) or `security-group` (dashed rose) encloses; the renderer computes the box with correct 30/50 padding automatically. Never hand-arithmetic a boundary again.
- **Connections** route like edges (`variant`, `fromSide`/`toSide`, `route: straight|orthogonal-h|orthogonal-v|auto`, `via`, `labelDx/labelDy/labelAt`). For a vertical labeled connection, push the label into the gap with `labelDy` (the validator will tell you if it lands on a box).
- The renderer auto-emits the two-rect `c-mask` pattern, draws arrows before boxes (z-order), builds the legend from the component types you used, and **fails fast on component overlap, off-canvas components/boundaries, unknown wraps/connection ids, label-vs-component collisions, and non-finite coordinates** — the same reliability the other four modes already had.

输出包含组件矩形、边界、连接点路径和标签位置。

**渲染器负责原本需手动调整的机械工作**,因此你只需选择坐标和定义含义:

- **自由坐标** —— `pos: [x, y]`为组件左上角坐标;`size: [w, h]`默认值为`[120, 60]`。与类型化模式不同,此处无泳道/阶段网格——可自由选择非对称布局。`meta.viewBox`为可选(自动适配组件 + 图例行)。
- **网格布局** —— 可选`layout.mode: "grid"`,为每个组件设置`row`/`col`(见上文)。非dagre布局;仅支持固定单元格间距。
- **基于`wraps`的边界** —— 列出`region`(虚线琥珀色)或`security-group`(虚线玫瑰色)包含的组件ID;渲染器会自动计算带有正确30/50内边距的边界框。无需再手动计算边界。
- **连接**与边的路由方式相同(`variant`、`fromSide`/`toSide`、`route: straight|orthogonal-h|orthogonal-v|auto`、`via`、`labelDx/labelDy/labelAt`)。对于垂直带标签的连接,使用`labelDy`将标签推入间隙(验证器会告知标签是否落在框上)。
- 渲染器自动生成双矩形`c-mask`图案,在组件框之前绘制箭头(Z轴顺序),根据你使用的组件类型构建图例,并**快速检测组件重叠、画布外组件/边界、未知wraps/连接ID、标签与组件碰撞以及非有限坐标**——与其他四种模式具有相同的可靠性。

Hand-placed fallback (no renderer available)

手动布局备选方案(无渲染器可用)

When Node/ajv can't run, copy
assets/template.html
and place SVG by hand. Study the worked diagram inside the template and
examples/web-app.html
for coordinate idioms, follow the Design System below, and run the self-review checklist before delivering.
当Node/ajv无法运行时,复制
assets/template.html
并手动放置SVG。参考模板内的示例图和
examples/web-app.html
的坐标惯例,遵循下方设计系统,并在交付前运行自我检查清单。

The Cardinal Rule: CSS classes, not inline colors

核心规则:使用CSS类,而非内联颜色

The theme toggle works by switching CSS custom properties. Hardcoded
fill="rgba(...)"
or
stroke="#22d3ee"
will NOT update on theme change. Always use the class system:
svg
<rect x="X" y="Y" width="W" height="H" rx="6" class="c-mask"/>
<rect x="X" y="Y" width="W" height="H" rx="6" class="c-backend" stroke-width="1.5"/>
<text x="CX" y="CY" class="t-primary" font-size="11" font-weight="600" text-anchor="middle">API Server</text>
<text x="CX" y="CY+16" class="t-muted" font-size="9" text-anchor="middle">FastAPI :8000</text>
主题切换通过切换CSS自定义属性实现。硬编码的
fill="rgba(...)"
stroke="#22d3ee"
不会随主题变化而更新。务必使用类系统:
svg
<rect x="X" y="Y" width="W" height="H" rx="6" class="c-mask"/>
<rect x="X" y="Y" width="W" height="H" rx="6" class="c-backend" stroke-width="1.5"/>
<text x="CX" y="CY" class="t-primary" font-size="11" font-weight="600" text-anchor="middle">API Server</text>
<text x="CX" y="CY+16" class="t-muted" font-size="9" text-anchor="middle">FastAPI :8000</text>

Design system

设计系统

Component fills
c-frontend
(clients/UI),
c-backend
(services/APIs),
c-database
(stores/caches),
c-cloud
(managed infra),
c-security
(auth/secrets),
c-messagebus
(Kafka/queues),
c-external
(3rd parties); text accents
t-<same>
plus neutrals
t-primary
/
t-muted
/
t-dim
. Arrows
a-default
,
a-emphasis
(hot path),
a-security
(dashed),
a-dashed
(async) — always set
stroke-width
and pair
marker-end="url(#arrowhead[-variant])"
with the matching class. Boundaries:
c-security-group
(dashed rose),
c-region
(dashed amber),
c-lane
(swimlane).
Typography inherits JetBrains Mono from the SVG root. Sizes: 11–12px component names, 9px sublabels, 8px annotations, 7px tiny labels.
组件填充类:
c-frontend
(客户端/UI)、
c-backend
(服务/API)、
c-database
(存储/缓存)、
c-cloud
(托管基础设施)、
c-security
(认证/密钥)、
c-messagebus
(Kafka/队列)、
c-external
(第三方);文本强调类:
t-<对应组件类>
加上中性类
t-primary
/
t-muted
/
t-dim
。箭头类:
a-default
a-emphasis
(主路径)、
a-security
(虚线)、
a-dashed
(异步)——务必设置
stroke-width
并搭配匹配的
marker-end="url(#arrowhead[-variant])"
。边界类:
c-security-group
(虚线玫瑰色)、
c-region
(虚线琥珀色)、
c-lane
(泳道)。
字体继承自SVG根节点的JetBrains Mono。字号:组件名称11–12px,子标签9px,注释8px,小标签7px。

Hard layout rules

硬性布局规则

  • Two-rect pattern everywhere: opaque
    c-mask
    rect first, styled
    c-<type>
    rect on top — semi-transparent fills otherwise let arrows bleed through.
  • Arrows before components in document order (SVG paints in order; arrows must sit behind boxes).
  • Vertical stacking: ≥40px gap between components; inline connectors (message buses, 20px tall) live inside the gap, never overlapping boxes.
  • Boundary padding: boundary
    y
    = inner
    y
    − 30, boundary
    height
    = inner
    height
    + 50, label baseline 18px below the boundary top.
  • Legend placement: outside ALL boundary boxes, ≥20px below the lowest one; grow the viewBox if needed.
  • 双矩形模式:先绘制不透明的
    c-mask
    矩形,再在上方绘制带样式的
    c-<type>
    矩形——否则半透明填充会让箭头透显。
  • 箭头在组件之前:在文档顺序中,
    <line>
    /
    <path>
    箭头需出现在所有组件矩形之前(SVG按绘制顺序渲染;箭头必须位于框后方)。
  • 垂直堆叠:组件间间隙≥40px;内联连接器(消息总线,高20px)放在间隙内,切勿与框重叠。
  • 边界内边距:边界
    y
    = 内部元素
    y
    − 30,边界
    height
    = 内部元素
    height
    + 50,标签基线位于边界顶部下方18px处。
  • 图例位置:位于所有边界框之外,低于最低元素≥20px;必要时扩大viewBox。

Self-review checklist (run before delivering)

自我检查清单(交付前运行)

  1. grep -E 'fill="(#|rgb)|stroke="(#|rgb)' out.html
    inside the SVG returns nothing except the template's own defs (Cardinal Rule).
  2. Every
    c-<type>
    rect has an identical-geometry
    c-mask
    rect immediately before it.
  3. All
    <line>
    /
    <path>
    arrows appear before all component rects in document order.
  4. Compute max(y + height) over all SVG elements: viewBox height must exceed it by ≥20px; same for x/width.
  5. Legend y is below every boundary's y + height.
  6. The
    .toolbar
    ,
    <script>
    blocks, and
    :root
    /
    [data-theme]
    CSS are untouched — they ARE the theme toggle and export menu.
  1. 在SVG内执行
    grep -E 'fill="(#|rgb)|stroke="(#|rgb)' out.html
    ,除模板自身的defs外无其他结果(核心规则)。
  2. 每个
    c-<type>
    矩形之前都有一个几何形状完全相同的
    c-mask
    矩形。
  3. 所有
    <line>
    /
    <path>
    箭头在文档顺序中出现在所有组件矩形之前。
  4. 计算所有SVG元素的max(y + height):viewBox高度必须超过该值≥20px;x/宽度同理。
  5. 图例y坐标低于所有边界的y + height。
  6. .toolbar
    <script>
    块以及
    :root
    /
    [data-theme]
    CSS未被修改——这些是主题切换和导出菜单的核心。

Output

输出结果

A single self-contained
.html
: embedded CSS (Google Fonts loads async and degrades to system monospace offline), inline SVG, ~19KB embedded JS for theme + export. It renders directly in any modern browser. Raster exports render natively at up to 4× the viewBox (large diagrams step down to 3×/2× to stay under canvas limits); the SVG download is dual-theme self-contained and follows the host's
prefers-color-scheme
(manual override via
svg[data-theme="..."]
).
单个独立的
.html
文件:内嵌CSS(Google Fonts异步加载,离线时降级为系统等宽字体)、内嵌SVG、约19KB的内嵌JS用于主题切换和导出。可直接在任何现代浏览器中渲染。栅格导出以最高4倍viewBox分辨率原生生成;大图表会自动降至3×/2×以避免超出画布限制;SVG下载为双主题独立文件,遵循宿主的
prefers-color-scheme
设置(可通过
svg[data-theme="..."]
手动覆盖)。