- skills/archify: vendored tt-a1i/archify 2.14.0 (MIT), pure Node 18+, zero deps - extensions/pi-mermaid: renders mermaid blocks as ASCII in TUI; deps beautiful-mermaid + mermaid - skills/project-diagramming-*: orchestration skills, per-project docs/ convention
Workflow Renderer
Render diagram_type: "workflow" JSON files into the standard Archify HTML
template.
node archify/renderers/workflow/render-workflow.mjs input.workflow.json output.html
The renderer validates input against archify/schemas/workflow.schema.json
with the bundled standalone validator. No dependency installation is required.
If output.html is omitted, the renderer uses meta.output from the JSON file
or falls back to workflow.html in the current working directory.
After rendering, run the artifact checker:
node archify/scripts/check-render-output.mjs output.html
It catches final-SVG issues that are easiest to see in a browser: non-finite SVG values, accidental two-point diagonal arrows, and arrows crossing the legend.
Input
Workflow JSON files must set:
{
"schema_version": 1,
"diagram_type": "workflow",
"meta": {
"title": "Agent Tool Call Workflow"
},
"lanes": [],
"phases": [],
"groups": [],
"mainPath": [],
"nodes": [],
"edges": [],
"cards": []
}
Omit meta.viewBox for the common case: the width is fixed at 720 and the
height is derived from the lane count, so lanes and legend always fit. A
complete worked example lives at
archify/examples/agent-tool-call.workflow.json.
The schema lives at:
archify/schemas/workflow.schema.json
Legend
The default legend derives component kinds from nodes[].type. Supported
meta.legend.entries keys, in stable order, are frontend, backend,
security, messagebus, database, cloud, and external. Labels and
visibility may be overridden through the shared legend contract; only kinds
backed by rendered nodes receive Semantic Legend controls.
Layout budget
| Constant | Value |
|---|---|
| viewBox | default [720, auto] — auto height = 52 + lanes×104 + (lanes−1)×20 + 124 |
| Lane frame | x 40, width 640, height 104, gap 20; first lane top at y 52 |
| Lane title strip | top 30px of each lane; node boxes must stay below it |
Column centers (col 0–5) |
x = 88, 220, 300, 430, 500, 625 |
| Phase headers | Optional phases[] render above the first lane, spanning fromCol..toCol |
| Lane groups | Optional groups[] frame parallel work or branch work inside one lane |
| Exception lanes | Set lane.variant: "exception" for retry, denial, fallback, or failure paths |
| Main path lint | Optional mainPath[] checks that happy-path steps have matching edges and do not move backward |
| Default node | 92×52 (height 68 when tag is set) |
| Node spacing | ≥8px between nodes in the same lane |
| Edge length | straight segments must span ≥28px |
| Legend row | y = lane bottom + 44; viewBox height must be ≥ legend y + 18 |
Column-center gaps are 132 / 80 / 130 / 70 / 125 px: columns 1↔2 (80px) and
3↔4 (70px) cannot both hold default-width 92px nodes in the same lane — skip a
column or reduce width.
Design Rules
- Use lanes for ownership or runtime boundaries.
- Use phase headers for high-level story beats such as Intake, Plan, Execute, and Report.
- Use groups for parallel checks, branch handling, or bounded work within a lane; every group must contain at least one node.
- Use
lane.variant: "exception"for human wait, denial, retry, fallback, and failure lanes instead of mixing those paths into the happy path. - Set
mainPathwhen the diagram has a clear happy path; the renderer validates that consecutive ids have matching edges and move left-to-right. - Place nodes with lane IDs and column indexes, not raw SVG coordinates.
- Leave short adjacent links unlabeled; the arrow is enough.
- Use labels for cross-lane decisions, approvals, async traces, and return paths.
- Prefer route presets —
drop(bend between lanes;bias0–1 picks where),outside-right,return-left,bottom-channel, andup-channel— before using rawviapoints.straightand the defaultautocover the rest. - Keep workflow examples compact enough to render well in narrow chat/browser previews.
Schema violations exit non-zero with path-prefixed messages annotated with the
element's id or label. The renderer additionally fails when it can detect
layout problems, including node overlap, nodes outside their lanes, invalid
phase/group column ranges, empty groups, broken mainPath steps, unknown edge
targets, labels colliding with nodes or other labels, labels wider than their
node, legends outside the viewBox, or straight arrows that are too short to
read cleanly. The shared Clean Flow Gate also rejects edges crossing unrelated
nodes with 2px clearance; lanes, phases, and groups remain intentional
pass-through containers. Text width is estimated CJK-aware: fullwidth glyphs
count as two units.
Set meta.quality_profile to showcase for polished delivery. Unrelated proper
X crossings then fail with composition/proper-crossing; default standard
keeps them as artifact-receipt warnings. Collinear lane corridors are outside
the proper-X rule, but a separate gate warns in standard and fails in
showcase when unrelated edges overlap for at least 8px. Shared semantic
endpoints, point touches, and shorter overlaps remain valid. Showcase also
rejects any route segment below 8px and any interior turn segment below 16px;
ordinary 8–15px endpoint stubs remain valid for fixed lane gaps.