archify
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseArchify 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 , respects ), 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 — ideal for GitHub READMEs), and a CSS-variable color system that keeps both themes consistent.
localStorageprefers-color-schemeprefers-color-scheme创建包含内嵌SVG、主题切换功能和内置图片/SVG导出菜单的独立HTML文件形式的专业技术图表。
每个图表都配备明暗主题切换器(状态存储在中,遵循设置)、导出菜单(将PNG复制到剪贴板;以最高4倍分辨率原生下载PNG/JPEG/WebP格式的栅格图;下载适配嵌入宿主的双主题SVG——非常适合GitHub README),以及确保双主题风格一致的CSS变量配色系统。
localStorageprefers-color-schemeprefers-color-schemeSetup (one-time, renderer modes only)
初始化设置(仅渲染器模式需执行一次)
The five typed renderers validate JSON against schemas via . From this skill's folder:
ajvbash
npm installWithout 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 following the Design System below, and run the self-review checklist before delivering.
assets/template.html五种类型的渲染器通过验证JSON与Schema的一致性。在本技能所在文件夹下执行:
ajvbash
npm install即使不执行该命令,渲染器仍可运行——此时会打印警告并跳过Schema验证,仅保留自身的布局检查。生成的HTML文件完全无依赖;仅渲染器存在依赖。
若完全无法访问命令行(例如该技能作为项目知识添加),则所有请求均采用架构模式:按照下方设计系统将SVG手动放入,并在交付前运行自我检查清单。
assets/template.htmlChoosing a Diagram Type
选择图表类型
| Type | Use for | How |
|---|---|---|
| System components, cloud resources, services, security boundaries, infrastructure | |
| Technical flows, approval gates, tool calls, runbooks, CI/CD, incident response | |
| API call chains, request lifecycles, cache fallback, async traces, return paths | |
| Pipelines, ETL/ELT, PII isolation, lineage, warehouse sync, consumers | |
| State machines, status transitions, wait states, retries, terminal states | |
Trigger phrases: "architecture/system/cloud diagram" → (unless clearly process-oriented). "workflow/flow/process/runbook/approval/CI-CD/incident" → . "sequence/interaction/call chain/who calls whom" → . "data flow/pipeline/ETL/lineage/PII/governance" → . "state/status/lifecycle/state machine/retry/terminal" → .
architectureworkflowsequencedataflowlifecycle| 类型 | 适用场景 | 实现方式 |
|---|---|---|
| 系统组件、云资源、服务、安全边界、基础设施 | |
| 技术流程、审批关卡、工具调用、运行手册、CI/CD、事件响应 | |
| API调用链、请求生命周期、缓存回退、异步追踪、返回路径 | |
| 数据管道、ETL/ELT、PII隔离、数据血缘、仓库同步、数据消费 | |
| 状态机、状态转换、等待状态、重试、终止状态 | |
触发短语:"架构/系统/云图" → (除非明确为流程导向)。"工作流/流程/过程/运行手册/审批/CI-CD/事件" → 。"序列/交互/调用链/谁调用谁" → 。"数据流/管道/ETL/数据血缘/PII/治理" → 。"状态/状态机/生命周期/重试/终止" → 。
architectureworkflowsequencedataflowlifecycleMermaid 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:
| Mermaid | Archify mode | Mapping |
|---|---|---|
| | |
| | |
| | states → states (pick |
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模式 | 映射规则 |
|---|---|---|
| | |
| | |
| | 状态 → 状态(从名称中选择 |
丢弃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:
- One main path — left → right (architecture) or lane → column (workflow). The reader should trace the happy path without crossing lines.
- Few labeled edges — label only cross-boundary or non-obvious transitions on the main path. Adjacent steps stay unlabeled.
- 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.
- Cards for detail — policies, tech stack notes, and "also connects to X" belong in summary cards, not as extra arrows.
- Mode fit — process / approval / tool-call stories → or
workflow. Component maps with ≤12 nodes →sequence. If the diagram needs 20+ edges, remove edges until the main path is obvious.architecture
Worked examples on this pattern: (this repo) and (third-party desktop app).
examples/archify-repo.architecture.jsonexamples/maka-architecture.architecture.jsonWhen validation fails on label overlap, read the Suggested fix lines (coordinates / / ) and apply them directly — do not guess offsets blindly.
labelAtlabelDyArchify的可读性源于空间叙事,而非绘制每一个依赖箭头。在编写坐标或边列表之前,先规划一条清晰的主线:
- 单一主路径 —— 从左到右(架构图)或泳道到列(工作流图)。读者应能无需交叉线条即可追踪正常流程。
- 少量带标签的边 —— 仅为主路径上跨边界或非显式转换添加标签。相邻步骤保持无标签。
- 简短分支 —— 权限、存储、机器人、CI:从主路径上最近的节点向上或向下连接。切勿让次要边斜跨无关组件。
- 卡片承载细节 —— 策略、技术栈说明以及"还连接到X"等内容应放在摘要卡片中,而非添加额外箭头。
- 模式匹配 —— 流程/审批/工具调用类场景 → 或
workflow。节点数≤12的组件图 →sequence。若图表需要20+条边,则删除边直到主路径清晰可见。architecture
该模式的示例:(本仓库)和(第三方桌面应用)。
examples/archify-repo.architecture.jsonexamples/maka-architecture.architecture.json当验证因标签重叠失败时,直接参考建议修复行(坐标//)进行调整——切勿盲目猜测偏移量。
labelAtlabelDyRenderer Modes (architecture / workflow / sequence / dataflow / lifecycle)
渲染器模式(architecture / workflow / sequence / dataflow / lifecycle)
All five modes follow the same loop:
- Read first: the schema () and the complete worked example (
schemas/<type>.schema.json) — copy its patterns instead of guessing field shapes.examples/*.{architecture,workflow,sequence,dataflow,lifecycle}.json - Write .
<name>.<type>.json - Render: (paths relative to this skill's folder).
node bin/archify.mjs render <type> <input>.json <output>.html - Validate the generated artifact: , or check an existing HTML file with
node bin/archify.mjs validate <type> <input>.json --json. This catches malformed SVG output, non-finite SVG values, two-point diagonal arrows, and arrows crossing the legend.node bin/archify.mjs check <output>.html - 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 . 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.
/nodes/3 (id/label: "router") must NOT have additional propertiesSet 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 , and leaves the default static output unchanged.
meta.animation: "trace"prefers-reduced-motion五种模式遵循相同流程:
- 先阅读:Schema文件()和完整示例(
schemas/<type>.schema.json)——复制其模式而非猜测字段格式。examples/*.{architecture,workflow,sequence,dataflow,lifecycle}.json - 编写文件。
<name>.<type>.json - 渲染:(路径相对于本技能所在文件夹)。
node bin/archify.mjs render <type> <input>.json <output>.html - 验证生成的产物:,或用
node bin/archify.mjs validate <type> <input>.json --json检查现有HTML文件。这会捕获格式错误的SVG输出、非有限SVG值、两点对角线箭头以及穿过图例的箭头。node bin/archify.mjs check <output>.html - 若任一步骤失败,错误信息会指出JSON路径或修复方案(阈值、有效范围、需调整的参数)。修复JSON后重新运行;切勿编辑渲染器。
Schema违规会以非零状态退出,并显示带路径前缀的消息,例如。渲染器还会快速检测布局问题:节点/状态重叠(包括跨泳道)、标签与节点或其他标签碰撞、标签宽于节点、列/行超出范围、边过短、工作流边跨无关节点、图例超出 viewBox。CJK文本会自动按双倍宽度计算。
/nodes/3 (id/label: "router") must NOT have additional properties仅当用户要求动态效果或演示视图时,设置。它会为渲染器标记的箭头和节点添加轻量SVG/CSS追踪动画,遵循设置,且不改变默认静态输出。
meta.animation: "trace"prefers-reduced-motionWorkflow
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 ( 0–5) at fixed x positions — 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 . Lane content width is 640px. Omit — the renderer sizes height to the lane count automatically. Use for top-of-diagram story beats, to frame parallel work or a branch inside one lane, and for error/retry/fallback lanes. 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: , (bend between lanes; 0–1 picks where), , , , , or explicit points. Keep adjacent-step edges unlabeled; reserve labels for cross-lane transitions, approvals, async traces, and returns.
col[88, 220, 300, 430, 500, 625]widthmeta.viewBoxphasesgroupslane.variant: "exception"mainPathstraightdropbiasoutside-rightreturn-leftbottom-channelup-channelviajson
{
"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列( 0–5),固定X坐标为——同一泳道中相邻的1↔2列和3↔4列间距仅70–80px,默认宽度(92px)的节点会重叠;需跳过一列或缩小。泳道内容宽度为640px。无需设置——渲染器会根据泳道数量自动调整高度。使用定义图表顶部的阶段节点,在单个泳道中框选并行工作或分支,用于错误/重试/回退泳道。可选但推荐:按顺序列出正常流程的节点ID,以便渲染器检测缺失的边或意外的反向移动。边路由方式:、(泳道间弯曲; 0–1选择弯曲位置)、、、、或显式点。相邻步骤的边保持无标签;仅为跨泳道转换、审批、异步追踪和返回添加标签。
col[88, 220, 300, 430, 500, 625]widthmeta.viewBoxphasesgroupslane.variant: "exception"mainPathstraightdropbiasoutside-rightreturn-leftbottom-channelup-channelviaSequence
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 must stay within ; messages that share horizontal space need ≥28px vertical separation; arrows need ≥60px horizontal span. and are y pixel coordinates, not participant ids. A taller (default ) buys more timeline room. Keep labels short: "GET /path", "verify JWT", "cache miss", "200 JSON".
y[160, viewBox_height − 83]segments[].from/toactivations[].from/tometa.viewBox[920, 760]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个参与者。消息必须在范围内;共享水平空间的消息需保持≥28px的垂直间距;箭头需≥60px的水平跨度。和是Y像素坐标,而非参与者ID。更大的(默认)可提供更多时间轴空间。标签保持简短:"GET /path"、"verify JWT"、"cache miss"、"200 JSON"。
y[160, viewBox_height − 83]segments[].from/toactivations[].from/tometa.viewBox[920, 760]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 ( 0–4) at y ; default node 112×58. Default viewBox . Flow labels are mandatory and asset-like ("clickstream", "identity map", "feature vectors"); put sensitivity in ("PII touch", "approved only", "non-PII"). Variants: = primary path, = PII/policy/consent, = async/batch.
row[128, 242, 356, 470, 584][940, 720]classificationemphasissecuritydashedjson
{
"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行( 0–4),y坐标为;默认节点尺寸112×58。默认viewBox为。流标签为必填项,且需体现资产属性("clickstream"、"identity map"、"feature vectors");敏感性信息放在中("PII touch"、"approved only"、"non-PII")。变体: = 主路径, = PII/政策/授权, = 异步/批量。
row[128, 242, 356, 470, 584][940, 720]classificationemphasissecuritydashedLifecycle
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: is required and maps to the top phase band (cols 0–4); 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 or . Band headers render from your lane labels. Default viewBox . Keep transition labels event-like and sparse ("retry", "timeout", "cancel"); prefer state s, numbers, and summary cards over label-heavy arrows. Put terminal states in the lane so endings are unambiguous.
mainterminalcolyOffset[980, 660]tagstepterminaljson
{
"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为语义化预留值:为必填项,对应顶部阶段带(列0–4);对应底部结果带(列0–2);其他所有泳道ID共享中间事件带(列0–2)——同一带中的状态通过不同或区分。带标题从泳道标签生成。默认viewBox为。转换标签保持类事件风格且尽量精简("retry"、"timeout"、"cancel");优先使用状态、编号和摘要卡片,而非带大量标签的箭头。将终止状态放在泳道中,确保结束状态清晰明确。
mainterminalcolyOffset[980, 660]tagstepterminalPer-mode deep guidance
各模式深度指南
Each renderer has a README with its full design language (route presets, semantic types, story guidance): , , , . Read the matching one before your first diagram of that mode in a session.
renderers/workflow/README.mdrenderers/sequence/README.mdrenderers/dataflow/README.mdrenderers/lifecycle/README.md每个渲染器都有包含完整设计语言(路由预设、语义类型、叙事指南)的README文件:、、、。在会话中首次创建某类图表前,先阅读对应README。
renderers/workflow/README.mdrenderers/sequence/README.mdrenderers/dataflow/README.mdrenderers/lifecycle/README.mdArchitecture 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>.htmlFree placement — is the component's top-left; defaults to . Unlike typed modes there is no lane/stage grid — asymmetric placement is yours to choose. is optional (auto-fitted).
pos: [x, y]size: [w, h][120, 60]meta.viewBoxGrid 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 }
]
}posexamples/archify-repo-grid.architecture.jsonInspect 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 }
]
}若存在则优先使用(覆盖单个单元格)。这并非自动布局——间距为固定单元格计算结果。示例:。
posexamples/archify-repo-grid.architecture.json检查布局(#9) —— 编辑JSON后,无需打开HTML即可导出计算后的盒模型:
bash
node bin/archify.mjs inspect architecture my.architecture.jsonor: 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 and place SVG by hand. Study the worked diagram inside the template and for coordinate idioms, follow the Design System below, and run the self-review checklist before delivering.
assets/template.htmlexamples/web-app.html当Node/ajv无法运行时,复制并手动放置SVG。参考模板内的示例图和的坐标惯例,遵循下方设计系统,并在交付前运行自我检查清单。
assets/template.htmlexamples/web-app.htmlThe Cardinal Rule: CSS classes, not inline colors
核心规则:使用CSS类,而非内联颜色
The theme toggle works by switching CSS custom properties. Hardcoded or will NOT update on theme change. Always use the class system:
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>主题切换通过切换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 (clients/UI), (services/APIs), (stores/caches), (managed infra), (auth/secrets), (Kafka/queues), (3rd parties); text accents plus neutrals / / . Arrows , (hot path), (dashed), (async) — always set and pair with the matching class. Boundaries: (dashed rose), (dashed amber), (swimlane).
c-frontendc-backendc-databasec-cloudc-securityc-messagebusc-externalt-<same>t-primaryt-mutedt-dima-defaulta-emphasisa-securitya-dashedstroke-widthmarker-end="url(#arrowhead[-variant])"c-security-groupc-regionc-laneTypography inherits JetBrains Mono from the SVG root. Sizes: 11–12px component names, 9px sublabels, 8px annotations, 7px tiny labels.
组件填充类:(客户端/UI)、(服务/API)、(存储/缓存)、(托管基础设施)、(认证/密钥)、(Kafka/队列)、(第三方);文本强调类:加上中性类 / / 。箭头类:、(主路径)、(虚线)、(异步)——务必设置并搭配匹配的。边界类:(虚线玫瑰色)、(虚线琥珀色)、(泳道)。
c-frontendc-backendc-databasec-cloudc-securityc-messagebusc-externalt-<对应组件类>t-primaryt-mutedt-dima-defaulta-emphasisa-securitya-dashedstroke-widthmarker-end="url(#arrowhead[-variant])"c-security-groupc-regionc-lane字体继承自SVG根节点的JetBrains Mono。字号:组件名称11–12px,子标签9px,注释8px,小标签7px。
Hard layout rules
硬性布局规则
- Two-rect pattern everywhere: opaque rect first, styled
c-maskrect on top — semi-transparent fills otherwise let arrows bleed through.c-<type> - 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 = inner
y− 30, boundaryy= innerheight+ 50, label baseline 18px below the boundary top.height - Legend placement: outside ALL boundary boxes, ≥20px below the lowest one; grow the viewBox if needed.
- 双矩形模式:先绘制不透明的矩形,再在上方绘制带样式的
c-mask矩形——否则半透明填充会让箭头透显。c-<type> - 箭头在组件之前:在文档顺序中,/
<line>箭头需出现在所有组件矩形之前(SVG按绘制顺序渲染;箭头必须位于框后方)。<path> - 垂直堆叠:组件间间隙≥40px;内联连接器(消息总线,高20px)放在间隙内,切勿与框重叠。
- 边界内边距:边界= 内部元素
y− 30,边界y= 内部元素height+ 50,标签基线位于边界顶部下方18px处。height - 图例位置:位于所有边界框之外,低于最低元素≥20px;必要时扩大viewBox。
Self-review checklist (run before delivering)
自我检查清单(交付前运行)
- inside the SVG returns nothing except the template's own defs (Cardinal Rule).
grep -E 'fill="(#|rgb)|stroke="(#|rgb)' out.html - Every rect has an identical-geometry
c-<type>rect immediately before it.c-mask - All /
<line>arrows appear before all component rects in document order.<path> - Compute max(y + height) over all SVG elements: viewBox height must exceed it by ≥20px; same for x/width.
- Legend y is below every boundary's y + height.
- The ,
.toolbarblocks, and<script>/:rootCSS are untouched — they ARE the theme toggle and export menu.[data-theme]
- 在SVG内执行,除模板自身的defs外无其他结果(核心规则)。
grep -E 'fill="(#|rgb)|stroke="(#|rgb)' out.html - 每个矩形之前都有一个几何形状完全相同的
c-<type>矩形。c-mask - 所有/
<line>箭头在文档顺序中出现在所有组件矩形之前。<path> - 计算所有SVG元素的max(y + height):viewBox高度必须超过该值≥20px;x/宽度同理。
- 图例y坐标低于所有边界的y + height。
- 、
.toolbar块以及<script>/:rootCSS未被修改——这些是主题切换和导出菜单的核心。[data-theme]
Output
输出结果
A single self-contained : 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 (manual override via ).
.htmlprefers-color-schemesvg[data-theme="..."]单个独立的文件:内嵌CSS(Google Fonts异步加载,离线时降级为系统等宽字体)、内嵌SVG、约19KB的内嵌JS用于主题切换和导出。可直接在任何现代浏览器中渲染。栅格导出以最高4倍viewBox分辨率原生生成;大图表会自动降至3×/2×以避免超出画布限制;SVG下载为双主题独立文件,遵循宿主的设置(可通过手动覆盖)。
.htmlprefers-color-schemesvg[data-theme="..."]