@stacksjs/defaults 0.74.41 → 0.74.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ai/skills/stacks-cms/SKILL.md +4 -4
- package/ai/skills/stacks-config/SKILL.md +1 -1
- package/ai/skills/stacks-technical-diagrams/LICENSE +1 -1
- package/ai/skills/stacks-technical-diagrams/SKILL.md +257 -229
- package/ai/skills/stacks-technical-diagrams/THIRD_PARTY_NOTICES.md +69 -0
- package/ai/skills/stacks-technical-diagrams/assets/JetBrainsMono-OFL.txt +93 -0
- package/ai/skills/stacks-technical-diagrams/assets/template.html +14588 -929
- package/ai/skills/stacks-technical-diagrams/bin/diagrams +10 -0
- package/ai/skills/stacks-technical-diagrams/bin/open-artifact.mjs +86 -0
- package/ai/skills/stacks-technical-diagrams/bin/preview.mjs +654 -0
- package/ai/skills/stacks-technical-diagrams/bin/technical-diagrams.mjs +1898 -89
- package/ai/skills/stacks-technical-diagrams/bin/visual-check.mjs +829 -0
- package/ai/skills/stacks-technical-diagrams/brand-marks/README.md +31 -0
- package/ai/skills/stacks-technical-diagrams/brand-marks/catalog.json +131 -0
- package/ai/skills/stacks-technical-diagrams/delta/architecture-delta.mjs +1221 -0
- package/ai/skills/stacks-technical-diagrams/examples/agent-run.lifecycle.json +18 -22
- package/ai/skills/stacks-technical-diagrams/examples/agent-tool-call.workflow.json +58 -52
- package/ai/skills/stacks-technical-diagrams/examples/async-job-roundtrip.sequence.json +61 -0
- package/ai/skills/stacks-technical-diagrams/examples/brand-aware-delivery.architecture.json +47 -0
- package/ai/skills/stacks-technical-diagrams/examples/cache-miss-request.sequence.json +30 -23
- package/ai/skills/stacks-technical-diagrams/examples/checkout-platform.base.architecture.json +31 -0
- package/ai/skills/stacks-technical-diagrams/examples/checkout-platform.head.architecture.json +31 -0
- package/ai/skills/stacks-technical-diagrams/examples/deployment-release.lifecycle.json +49 -0
- package/ai/skills/stacks-technical-diagrams/examples/event-stream.dataflow.json +57 -0
- package/ai/skills/stacks-technical-diagrams/examples/incident-response.workflow.json +64 -0
- package/ai/skills/stacks-technical-diagrams/examples/product-analytics.dataflow.json +22 -16
- package/ai/skills/stacks-technical-diagrams/examples/production-deployment.architecture.json +71 -0
- package/ai/skills/stacks-technical-diagrams/examples/release-delivery.workflow.json +62 -0
- package/ai/skills/stacks-technical-diagrams/examples/web-app.architecture.json +16 -11
- package/ai/skills/stacks-technical-diagrams/migrations/workflow-v2.mjs +279 -0
- package/ai/skills/stacks-technical-diagrams/recipes/scenarios.mjs +391 -0
- package/ai/skills/stacks-technical-diagrams/references/authoring-contract.md +243 -0
- package/ai/skills/stacks-technical-diagrams/references/brand-marks.md +65 -0
- package/ai/skills/stacks-technical-diagrams/references/delivery-contract.md +120 -0
- package/ai/skills/stacks-technical-diagrams/references/viewer-runtime.md +45 -0
- package/ai/skills/stacks-technical-diagrams/renderers/architecture/render-architecture.mjs +780 -73
- package/ai/skills/stacks-technical-diagrams/renderers/dataflow/README.md +25 -3
- package/ai/skills/stacks-technical-diagrams/renderers/dataflow/render-dataflow.mjs +240 -52
- package/ai/skills/stacks-technical-diagrams/renderers/lifecycle/README.md +31 -7
- package/ai/skills/stacks-technical-diagrams/renderers/lifecycle/render-lifecycle.mjs +227 -50
- package/ai/skills/stacks-technical-diagrams/renderers/sequence/README.md +36 -6
- package/ai/skills/stacks-technical-diagrams/renderers/sequence/render-sequence.mjs +270 -63
- package/ai/skills/stacks-technical-diagrams/renderers/shared/brand-marks.mjs +563 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/bun-runtime.mjs +20 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/cli.mjs +186 -10
- package/ai/skills/stacks-technical-diagrams/renderers/shared/desktop-readability.mjs +26 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/diagnostics.mjs +127 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/engineering-profiles.mjs +157 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/generated-brand-marks.mjs +2003 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/generated-validators.mjs +3 -3
- package/ai/skills/stacks-technical-diagrams/renderers/shared/geometry.mjs +1195 -2
- package/ai/skills/stacks-technical-diagrams/renderers/shared/i18n.mjs +595 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/legend.mjs +217 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/output-path.mjs +340 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/repository-evidence.mjs +238 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/repository-location.mjs +58 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/text-fit.mjs +49 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/utils.mjs +163 -19
- package/ai/skills/stacks-technical-diagrams/renderers/shared/validator.mjs +51 -5
- package/ai/skills/stacks-technical-diagrams/renderers/workflow/README.md +137 -17
- package/ai/skills/stacks-technical-diagrams/renderers/workflow/render-workflow.mjs +24 -470
- package/ai/skills/stacks-technical-diagrams/renderers/workflow/workflow-compiler.mjs +4400 -0
- package/ai/skills/stacks-technical-diagrams/renderers/workflow/workflow-migration-geometry.mjs +144 -0
- package/ai/skills/stacks-technical-diagrams/schemas/README.md +154 -11
- package/ai/skills/stacks-technical-diagrams/schemas/architecture.schema.json +61 -4
- package/ai/skills/stacks-technical-diagrams/schemas/common.schema.json +72 -0
- package/ai/skills/stacks-technical-diagrams/schemas/dataflow.schema.json +40 -18
- package/ai/skills/stacks-technical-diagrams/schemas/lifecycle.schema.json +43 -18
- package/ai/skills/stacks-technical-diagrams/schemas/sequence.schema.json +41 -4
- package/ai/skills/stacks-technical-diagrams/schemas/workflow.schema.json +97 -1
- package/ai/skills/stacks-technical-diagrams/scripts/check-render-output.mjs +551 -12
- package/ai/skills/stacks-technical-diagrams/scripts/render-examples.mjs +3 -4
- package/ide/vscode/package.json +1 -1
- package/package.json +2 -2
|
@@ -183,10 +183,10 @@ cms.comments.deleteComment(id: number): Promise<void>
|
|
|
183
183
|
title: 'Stacks Blog',
|
|
184
184
|
description: 'The official Stacks.js blog',
|
|
185
185
|
postsPerPage: 10,
|
|
186
|
-
enableComments: true,
|
|
187
|
-
enableRss: true,
|
|
188
|
-
enableSitemap: true,
|
|
189
|
-
enableSearch: true,
|
|
186
|
+
enableComments: true, // declared, NOT yet honoured by the static builder
|
|
187
|
+
enableRss: true, // generates feed.xml
|
|
188
|
+
enableSitemap: true, // generates sitemap.xml
|
|
189
|
+
enableSearch: true, // declared, NOT yet honoured by the static builder
|
|
190
190
|
social: { twitter: '@stacksjs', github: 'stacksjs/stacks' },
|
|
191
191
|
theme: { primaryColor: '#3451b2', logo: '/images/logos/logo-transparent.svg' },
|
|
192
192
|
}
|
|
@@ -110,7 +110,7 @@ they name: `defineEvents` and `defineListener` from `@stacksjs/events`,
|
|
|
110
110
|
### Features
|
|
111
111
|
| File | Type | Key Settings |
|
|
112
112
|
|------|------|-------------|
|
|
113
|
-
| `blog.ts` | BlogConfig | subdomain, postsPerPage,
|
|
113
|
+
| `blog.ts` | BlogConfig | subdomain, postsPerPage, enableRss/enableSitemap (enableComments and enableSearch are declared but not yet honoured) |
|
|
114
114
|
| `cms.ts` | CmsConfig | content management settings |
|
|
115
115
|
| `saas.ts` | SaasConfig | plans (Hobby/Pro/Lifetime with pricing), webhook, currencies |
|
|
116
116
|
| `ui.ts` | HeadwindOptions | content, output, minify |
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
3
|
Copyright (c) 2026 tt-a1i (Archify)
|
|
4
|
-
Copyright (c) 2025 Cocoon AI
|
|
4
|
+
Copyright (c) 2025 Cocoon AI
|
|
5
5
|
|
|
6
6
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
7
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -1,259 +1,285 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: stacks-technical-diagrams
|
|
3
|
-
description: Create polished,
|
|
3
|
+
description: Create polished, validated architecture, workflow, sequence, data-flow, and lifecycle diagrams for Stacks applications as explorable standalone HTML with inline SVG, dark/light themes, four visual presets, optional trace motion, and PNG/JPEG/WebP/SVG/WebM export. Accepts plain-language requirements or pasted Mermaid; reads repository evidence when the diagram must reflect real code; compares two architecture snapshots as a Before/Delta/After review. Use for system or cloud architecture, security boundaries, network topology, technical workflows, CI/CD, runbooks, API call sequences, request lifecycles, data pipelines, lineage, PII boundaries, state machines, status transitions, or converting Mermaid into a purpose-built diagram.
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
6
|
source: tt-a1i/archify
|
|
7
|
-
source_version: "2.
|
|
8
|
-
source_commit:
|
|
7
|
+
source_version: "2.17.0-dev.1"
|
|
8
|
+
source_commit: 18911058008f17dc065af23a2cdc9bfeff6d3f7a
|
|
9
9
|
based_on: Cocoon-AI/architecture-diagram-generator (MIT, v1.0)
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# Technical Diagrams for Stacks
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Turn a small typed JSON specification into one self-contained, interactive HTML diagram. Static
|
|
15
|
+
output is the default; motion is opt-in.
|
|
15
16
|
|
|
16
|
-
Every
|
|
17
|
+
Every delivered artifact carries a theme toggle (persists in `localStorage`, respects
|
|
18
|
+
`prefers-color-scheme`), pan/zoom, node search, focus with authored upstream/downstream reach, route
|
|
19
|
+
probing, a semantic lens, an overview radar, presentation mode, guided stories, and an export menu
|
|
20
|
+
(clipboard PNG; PNG/JPEG/WebP raster at up to 4x; dual-theme SVG; WebM for motion; 1200x630 share
|
|
21
|
+
cards). Those are reader capabilities that already exist in the output, not authoring work.
|
|
17
22
|
|
|
18
23
|
## Attribution
|
|
19
24
|
|
|
20
|
-
This skill ports the renderer and
|
|
25
|
+
This skill ports the renderer, validator, and viewer from
|
|
26
|
+
[Archify](https://github.com/tt-a1i/archify) 2.17.0-dev.1 by tt-a1i under the MIT license. Archify is
|
|
27
|
+
itself a fork and rewrite of Cocoon AI's `architecture-diagram-generator` 1.0. Preserve `LICENSE` and
|
|
28
|
+
`THIRD_PARTY_NOTICES.md` when redistributing this skill or substantial portions of its source.
|
|
21
29
|
|
|
22
|
-
##
|
|
30
|
+
## Running the CLI
|
|
23
31
|
|
|
24
|
-
|
|
32
|
+
Every command below is one launcher invocation from the Stacks project root:
|
|
25
33
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
1. Inspect the implementation before drawing. Treat `app/` as overrides and `storage/framework/defaults/app/` as fallbacks. Follow registrations in `app/Routes.ts`, route files, actions, jobs, listeners, middleware, models, config, resources, and framework entry points that matter to the requested view.
|
|
31
|
-
2. Read the relevant Stacks domain skill before mapping an unfamiliar subsystem. Common companions include `stacks-router`, `stacks-actions`, `stacks-models`, `stacks-database`, `stacks-jobs`, `stacks-events`, `stacks-realtime`, and `stacks-cloud`.
|
|
32
|
-
3. Draw one question per diagram. For a runtime overview, prefer browser or client -> stx/router -> action or service -> model/query -> database, then add only the external systems and trust boundaries needed for that story.
|
|
33
|
-
4. Write output to the user's requested path. When no path is given, use `docs/public/diagrams/<descriptive-name>/index.html` and keep the source JSON beside it. That path matters: BunPress only renders `docs/**/*.md` and copies `docs/public/**`, so a diagram written anywhere else under `docs/` never reaches the built site. The directory-plus-`index.html` shape is what the deployed docs host serves at the clean URL `/docs/diagrams/<descriptive-name>` - a bare `<name>.html` is redirected to an extensionless path that does not exist. Link to it from a docs page as `/diagrams/<descriptive-name>` (BunPress adds the `/docs` base).
|
|
34
|
-
|
|
35
|
-
If Bun cannot run, fall back to architecture mode: copy `assets/template.html`, hand-place SVG using the design system below, and run the self-review checklist before delivering.
|
|
36
|
-
|
|
37
|
-
## Choosing a Diagram Type
|
|
38
|
-
|
|
39
|
-
| Type | Use for | How |
|
|
40
|
-
|------|---------|-----|
|
|
41
|
-
| `architecture` | System components, cloud resources, services, security boundaries, infrastructure | `renderers/architecture/render-architecture.mjs` + JSON (or hand-place SVG when renderers can't run) |
|
|
42
|
-
| `workflow` | Technical flows, approval gates, tool calls, runbooks, CI/CD, incident response | `renderers/workflow/render-workflow.mjs` + JSON |
|
|
43
|
-
| `sequence` | API call chains, request lifecycles, cache fallback, async traces, return paths | `renderers/sequence/render-sequence.mjs` + JSON |
|
|
44
|
-
| `dataflow` | Pipelines, ETL/ELT, PII isolation, lineage, warehouse sync, consumers | `renderers/dataflow/render-dataflow.mjs` + JSON |
|
|
45
|
-
| `lifecycle` | State machines, status transitions, wait states, retries, terminal states | `renderers/lifecycle/render-lifecycle.mjs` + JSON |
|
|
46
|
-
|
|
47
|
-
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`.
|
|
48
|
-
|
|
49
|
-
## Mermaid as an Input Dialect
|
|
50
|
-
|
|
51
|
-
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 diagram mode:
|
|
52
|
-
|
|
53
|
-
| Mermaid | Diagram mode | Mapping |
|
|
54
|
-
|---------|--------------|---------|
|
|
55
|
-
| `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 |
|
|
56
|
-
| `sequenceDiagram` | `sequence` | `participant` → participants (pick semantic `type` from the name); `->>` → message, `-->>` → `return` variant; `Note` → message `note`; `rect` blocks → segments |
|
|
57
|
-
| `stateDiagram` | `lifecycle` | states → states (pick `start`/`active`/`waiting`/`success`/`failure` from names); `[*]` start/end → `start` type / `terminal` lane; transition labels → event-like labels |
|
|
58
|
-
|
|
59
|
-
Drop Mermaid styling; keep only the topology and meaning. You choose grouping, lane order, and what deserves emphasis - that judgment is the product.
|
|
60
|
-
|
|
61
|
-
## Layout principles (read before placing)
|
|
62
|
-
|
|
63
|
-
The renderer'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:
|
|
64
|
-
|
|
65
|
-
1. **One main path** - left → right (architecture) or lane → column (workflow). The reader should trace the happy path without crossing lines.
|
|
66
|
-
2. **Few labeled edges** - label only cross-boundary or non-obvious transitions on the main path. Adjacent steps stay unlabeled.
|
|
67
|
-
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.
|
|
68
|
-
4. **Cards for detail** - policies, tech stack notes, and "also connects to X" belong in summary cards, not as extra arrows.
|
|
69
|
-
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.
|
|
70
|
-
|
|
71
|
-
Use the complete examples in `examples/` as the starting point for each renderer mode.
|
|
72
|
-
|
|
73
|
-
When validation fails on label overlap, read the **Suggested fix** lines (coordinates / `labelAt` / `labelDy`) and apply them directly - do not guess offsets blindly.
|
|
34
|
+
```bash
|
|
35
|
+
.claude/skills/stacks-technical-diagrams/bin/diagrams doctor
|
|
36
|
+
```
|
|
74
37
|
|
|
75
|
-
|
|
38
|
+
The launcher runs Bun against the skill's own empty `bunfig.toml` with `--no-env-file`, so a diagram
|
|
39
|
+
render never inherits the application's `preload` chain or its `.env`. Never call the renderers with
|
|
40
|
+
a bare `bun`; use the launcher (or `bun --config=<skill>/bunfig.toml --no-env-file
|
|
41
|
+
<skill>/bin/technical-diagrams.mjs` if you need the explicit form).
|
|
42
|
+
|
|
43
|
+
Commands: `render`, `validate`, `deliver`, `compare`, `preview`, `visual-check`, `check`, `inspect`,
|
|
44
|
+
`migrate`, `guide`, `brands`, `examples`, `doctor`, `demo`. Run `diagrams` with no arguments for the
|
|
45
|
+
full usage block.
|
|
46
|
+
|
|
47
|
+
## Fast authoring path
|
|
48
|
+
|
|
49
|
+
Use this bounded path for ordinary generation.
|
|
50
|
+
|
|
51
|
+
1. Choose `architecture`, `workflow`, `sequence`, `dataflow`, or `lifecycle` from the question. When
|
|
52
|
+
ambiguous, run `diagrams guide "<scenario>" --json`.
|
|
53
|
+
2. Read one matching schema in `schemas/`, plus `schemas/common.schema.json`, plus one matching JSON
|
|
54
|
+
example in `examples/`. Read only those files. Use the example for field shape, never for facts.
|
|
55
|
+
New workflow sources use `schema_version: 2`; keep `schema_version: 1` only when preserving an
|
|
56
|
+
existing workflow's fixed geometry.
|
|
57
|
+
3. Artifact first: the next tool action writes the candidate JSON. Do not plan exact coordinates in
|
|
58
|
+
prose and do not read renderer internals before the first candidate. Start with one clear main
|
|
59
|
+
path, short side branches, sparse labels, and at most 12 primary nodes. Set
|
|
60
|
+
`meta.quality_profile: "showcase"` unless the user explicitly wants a dense `standard` map. Start
|
|
61
|
+
with automatic routes and labels; do not add `via`, `channelX`, `channelY`, or `labelAt` before a
|
|
62
|
+
diagnostic asks for one, and apply at most one diagnosed geometry control per repair.
|
|
63
|
+
4. Validate after every candidate edit and immediately before handoff:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
.claude/skills/stacks-technical-diagrams/bin/diagrams validate <type> <candidate.json> --quality showcase --json
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
A receipt with only 4 artifact checks is basic validation, never showcase acceptance. A showcase
|
|
70
|
+
pass reports all 9 artifact checks with 0 composition errors and 0 warnings. For a workflow v2
|
|
71
|
+
geometry diagnosis, run `validate workflow <candidate.json> --layout-json` and read the stable
|
|
72
|
+
compiler receipt; solver internals are not authoring controls. A passing final validation freezes
|
|
73
|
+
the candidate: do not edit it afterward.
|
|
74
|
+
5. Deliver once, as the final acceptance step:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
.claude/skills/stacks-technical-diagrams/bin/diagrams deliver <type> <candidate.json> <output.html> --quality showcase --json
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
A non-zero exit is never success. On failure, change only the diagnosed `subject`, verify
|
|
81
|
+
`evidence`, choose from `supportedFixes`, and rerun. Keep correcting while the objective error
|
|
82
|
+
count reaches a new minimum; if two consecutive rounds do not improve that best count, stop and
|
|
83
|
+
report the unresolved diagnostics truthfully.
|
|
84
|
+
|
|
85
|
+
Inspect renderer or validator source only after an unsupported internal diagnostic or two failed
|
|
86
|
+
focused repairs.
|
|
76
87
|
|
|
77
|
-
|
|
88
|
+
## Stacks repository workflow
|
|
78
89
|
|
|
79
|
-
1.
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
90
|
+
1. Inspect the implementation before drawing. Treat `app/` as overrides and
|
|
91
|
+
`storage/framework/defaults/app/` as fallbacks. Follow registrations in `app/Routes.ts`, route
|
|
92
|
+
files, actions, jobs, listeners, middleware, models, config, resources, and the framework entry
|
|
93
|
+
points that matter to the requested view.
|
|
94
|
+
2. Read the relevant Stacks domain skill before mapping an unfamiliar subsystem. Common companions
|
|
95
|
+
are `stacks-router`, `stacks-actions`, `stacks-models`, `stacks-database`, `stacks-jobs`,
|
|
96
|
+
`stacks-events`, `stacks-realtime`, and `stacks-cloud`.
|
|
97
|
+
3. Draw one question per diagram. For a runtime overview, prefer browser or client -> stx/router ->
|
|
98
|
+
action or service -> model/query -> database, then add only the external systems and trust
|
|
99
|
+
boundaries that story needs.
|
|
100
|
+
4. Write output to the user's requested path. When no path is given, use
|
|
101
|
+
`docs/public/diagrams/<descriptive-name>/index.html` and keep the source JSON beside it. That
|
|
102
|
+
path matters: BunPress only renders `docs/**/*.md` and copies `docs/public/**`, so a diagram
|
|
103
|
+
written anywhere else under `docs/` never reaches the built site. The directory-plus-`index.html`
|
|
104
|
+
shape is what the deployed docs host serves at the clean URL
|
|
105
|
+
`/docs/diagrams/<descriptive-name>`; a bare `<name>.html` is redirected to an extensionless path
|
|
106
|
+
that does not exist. Link to it from a docs page as `/diagrams/<descriptive-name>` (BunPress adds
|
|
107
|
+
the `/docs` base).
|
|
108
|
+
|
|
109
|
+
To pin architecture nodes to real code, pass `--repo-root .` and author `meta.repository`; nodes then
|
|
110
|
+
mark themselves `SRC n` and open Git-verified files and line ranges at one pinned commit. See
|
|
111
|
+
`references/authoring-contract.md`.
|
|
112
|
+
|
|
113
|
+
## Type router
|
|
114
|
+
|
|
115
|
+
| Type | Use for |
|
|
116
|
+
|---|---|
|
|
117
|
+
| `architecture` | Components, services, cloud/security boundaries, infrastructure |
|
|
118
|
+
| `workflow` | Processes, approval gates, tool calls, runbooks, CI/CD, incident response |
|
|
119
|
+
| `sequence` | API call chains, request lifecycles, cache fallback, async traces, returns |
|
|
120
|
+
| `dataflow` | Pipelines, ETL/ELT, lineage, PII and governance boundaries, consumers |
|
|
121
|
+
| `lifecycle` | State/status transitions, retries, waiting and terminal states |
|
|
122
|
+
|
|
123
|
+
Trigger phrases: "architecture/system/cloud diagram" -> `architecture` (unless clearly
|
|
124
|
+
process-oriented). "workflow/flow/process/runbook/approval/CI-CD/incident" -> `workflow`.
|
|
125
|
+
"sequence/interaction/call chain/who calls whom" -> `sequence`. "data
|
|
126
|
+
flow/pipeline/ETL/lineage/PII/governance" -> `dataflow`. "state/status/lifecycle/state
|
|
127
|
+
machine/retry/terminal" -> `lifecycle`.
|
|
128
|
+
|
|
129
|
+
## Mermaid input
|
|
130
|
+
|
|
131
|
+
Read Mermaid for topology and meaning, then author fresh JSON. Do not parse or re-render Mermaid
|
|
132
|
+
styling.
|
|
133
|
+
|
|
134
|
+
- `flowchart` / `graph` -> `workflow`, or `architecture` for a component map. `subgraph` becomes a
|
|
135
|
+
lane or a boundary; a diamond node becomes a decision or security node.
|
|
136
|
+
- `sequenceDiagram` -> `sequence`. `participant` becomes a semantic participant, `->>` a message,
|
|
137
|
+
`-->>` a `return` variant, `Note` a message note, `rect` a segment.
|
|
138
|
+
- `stateDiagram` -> `lifecycle`. `[*]` becomes the `start` type or the `terminal` lane; transition
|
|
139
|
+
labels stay event-like.
|
|
140
|
+
|
|
141
|
+
Drop Mermaid styling and keep only topology and meaning. Grouping, lane order, and emphasis are your
|
|
142
|
+
judgment, and that judgment is the product.
|
|
143
|
+
|
|
144
|
+
## Authoring invariants
|
|
145
|
+
|
|
146
|
+
- One obvious main path; side branches leave the nearest main-path node. Remove low-value edges
|
|
147
|
+
before adding routing controls. If a diagram needs 20+ edges, remove edges until the main path is
|
|
148
|
+
obvious.
|
|
149
|
+
- Detail belongs in summary `cards`, not in extra arrows.
|
|
150
|
+
- Omit `meta.visual_preset` by default so every diagram opens in `classic`. Color mode and visual
|
|
151
|
+
preset are independent: switching light/dark preserves the preset. Set `signal-flow`, `blueprint`,
|
|
152
|
+
or `editorial` only when the user asks for that style.
|
|
153
|
+
- Omit `meta.subtitle` by default. Never invent one that restates the title, nodes, or cards.
|
|
154
|
+
- Omit `meta.legend` for the truthful `auto` default. When needed, use only `mode: auto|all|hidden`
|
|
155
|
+
and renderer-supported `entries.<kind>.label|visible`. Labels never change semantics.
|
|
156
|
+
- Component types are `frontend`, `backend`, `database`, `cloud`, `security`, `messagebus`,
|
|
157
|
+
`external`. Variants are `default`, `emphasis`, `security`, `dashed`.
|
|
158
|
+
- Relationship labels are semantic data. When one collides, move the label, adjust the route or
|
|
159
|
+
spacing, then shorten the wording while preserving meaning. Delete wording only when both endpoints
|
|
160
|
+
fully imply it and it carries no protocol, action, direction, sync/async behavior, or
|
|
161
|
+
cross-boundary mechanism. Deleting a meaningful label is not a geometry repair.
|
|
162
|
+
- Spacing means clear gap, not center distance. A label's clear gap must exceed its measured mask
|
|
163
|
+
width.
|
|
164
|
+
- Automatic routes own their endpoint sides: the first and final segment leave and enter
|
|
165
|
+
perpendicular to that side. Automatic Port Spread is default behavior for architecture, workflow,
|
|
166
|
+
dataflow, and lifecycle; it stands down for explicit `via`, `channelX`, `channelY`, `labelAt`, or a
|
|
167
|
+
non-`auto` route.
|
|
168
|
+
- Never accept an edge crossing an unrelated opaque node, an ambiguous shared corridor, or a label
|
|
169
|
+
masking another route.
|
|
170
|
+
- For sequence diagrams, omit `meta.column_fit` for the stable `fixed` layout. Set `"spread"` when a
|
|
171
|
+
wide viewBox leaves unused horizontal space or meaningful participant labels do not fit; do not
|
|
172
|
+
shorten semantic labels first.
|
|
173
|
+
- Lifecycle phase columns `0..4` occupy the main rail; an event or terminal column `N` in `0..2`
|
|
174
|
+
aligns beneath main column `N + 2`. A recoverable state uses `type: "failure"` plus a real
|
|
175
|
+
transition back to the active state.
|
|
176
|
+
- Omit `meta.engineering_profile` by default. Enable `deployment-ownership` only when the user
|
|
177
|
+
explicitly asks for production deployment topology, ownership handoff, or a fail-closed deployment
|
|
178
|
+
review, and the facts are known. It fails closed on missing owners, region placement, private
|
|
179
|
+
database scope, or named crossings; repair the facts rather than removing the profile.
|
|
180
|
+
- Set `meta.animation: "trace"` only for a demo or presentation view. It respects
|
|
181
|
+
`prefers-reduced-motion` and leaves static output unchanged.
|
|
182
|
+
- `meta.views` is optional: at most five curated chapters built from stable node IDs.
|
|
183
|
+
- `meta.locale` (`en` or `zh-CN`) localizes renderer-owned viewer UI only, never authored content.
|
|
184
|
+
For any other language, omit it and say plainly that the fixed viewer UI and `<html lang>` fall
|
|
185
|
+
back to English.
|
|
186
|
+
- Treat the artifact as a first-screen desktop composition. One responsive artifact serves laptops
|
|
187
|
+
and external displays; never emit device-specific HTML or alternate topology. Before handoff the
|
|
188
|
+
page must not scroll horizontally or vertically at 1440x900, 1600x1000, and 1920x1080 (plus
|
|
189
|
+
2048x1320 for a large-display composition). Repair overflow by removing genuinely redundant content
|
|
190
|
+
or compacting spacing before shrinking nodes or labels. Never counterfeit a pass with
|
|
191
|
+
`overflow: hidden`, clipping, an internal scroller, a stretched SVG, or smaller typography.
|
|
192
|
+
|
|
193
|
+
Read `references/authoring-contract.md` only when you need field enums, spacing math, geometry repair
|
|
194
|
+
rules, repository evidence, or mode-specific placement.
|
|
195
|
+
|
|
196
|
+
## Delivery evidence
|
|
197
|
+
|
|
198
|
+
`deliver` freezes the specification bytes into a private same-directory snapshot, renders and checks
|
|
199
|
+
that snapshot, atomically commits the HTML, and reports SHA-256 plus byte counts for both
|
|
200
|
+
specification and artifact. It proves deterministic artifact checks; it does not exercise the viewer
|
|
201
|
+
in a browser.
|
|
84
202
|
|
|
85
|
-
|
|
203
|
+
```bash
|
|
204
|
+
.claude/skills/stacks-technical-diagrams/bin/diagrams visual-check <output.html> --json
|
|
205
|
+
```
|
|
86
206
|
|
|
87
|
-
|
|
207
|
+
`visual-check` drives a system Chrome over the DevTools Protocol against the exact delivered HTML,
|
|
208
|
+
without rerendering it, and writes screenshots plus a machine-readable receipt. It exits 2 (skipped)
|
|
209
|
+
when no Chrome is installed. Keep three claims separate: `deliver` proves artifact checks,
|
|
210
|
+
`visual-check` proves bounded browser behavior, and perceptual review requires a human or an
|
|
211
|
+
image-capable reviewer. Never run `visual-check` after a failed delivery: it would inspect the stale
|
|
212
|
+
last-good artifact.
|
|
88
213
|
|
|
89
|
-
|
|
214
|
+
For an active authoring loop, `preview` watches one JSON file on a random loopback port and reloads
|
|
215
|
+
only after a candidate passes every gate, keeping the last verified diagram visible through failures:
|
|
90
216
|
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
"schema_version": 1,
|
|
94
|
-
"diagram_type": "workflow",
|
|
95
|
-
"meta": { "title": "Release Workflow", "subtitle": "PR to production", "output": "release.html" },
|
|
96
|
-
"lanes": [ { "id": "dev", "label": "Developer" }, { "id": "ci", "label": "CI" }, { "id": "exceptions", "label": "Exception Handling", "variant": "exception" } ],
|
|
97
|
-
"phases": [ { "id": "intake", "label": "Intake", "fromCol": 0, "toCol": 1 } ],
|
|
98
|
-
"groups": [ { "id": "checks", "label": "Parallel checks", "lane": "ci", "fromCol": 1, "toCol": 3, "variant": "emphasis" } ],
|
|
99
|
-
"mainPath": ["pr", "build"],
|
|
100
|
-
"nodes": [
|
|
101
|
-
{ "id": "pr", "lane": "dev", "col": 0, "type": "frontend", "label": "Open PR", "sublabel": "feature branch" },
|
|
102
|
-
{ "id": "build", "lane": "ci", "col": 1, "type": "backend", "label": "Build", "sublabel": "lint + test", "tag": "blocking" }
|
|
103
|
-
],
|
|
104
|
-
"edges": [
|
|
105
|
-
{ "from": "pr", "to": "build", "label": "webhook", "variant": "emphasis", "fromSide": "bottom", "toSide": "top", "route": "drop" }
|
|
106
|
-
],
|
|
107
|
-
"cards": []
|
|
108
|
-
}
|
|
217
|
+
```bash
|
|
218
|
+
.claude/skills/stacks-technical-diagrams/bin/diagrams preview <type> <input>.json <output>.html --quality showcase
|
|
109
219
|
```
|
|
110
220
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
### Sequence
|
|
114
|
-
|
|
115
|
-
```json
|
|
116
|
-
{
|
|
117
|
-
"schema_version": 1,
|
|
118
|
-
"diagram_type": "sequence",
|
|
119
|
-
"meta": { "title": "Cache Miss Request", "subtitle": "auth and cache fallback", "output": "cache-miss.html" },
|
|
120
|
-
"participants": [
|
|
121
|
-
{ "id": "web", "type": "frontend", "label": "Web App", "sublabel": "React UI" },
|
|
122
|
-
{ "id": "api", "type": "backend", "label": "API", "sublabel": "handler" }
|
|
123
|
-
],
|
|
124
|
-
"segments": [ { "from": 160, "to": 320, "label": "01 / AUTH" } ],
|
|
125
|
-
"messages": [
|
|
126
|
-
{ "from": "web", "to": "api", "y": 200, "label": "GET /data", "variant": "emphasis" },
|
|
127
|
-
{ "from": "api", "to": "web", "y": 290, "label": "200 JSON", "variant": "return" }
|
|
128
|
-
],
|
|
129
|
-
"activations": [ { "participant": "api", "from": 190, "to": 300, "type": "backend" } ],
|
|
130
|
-
"cards": []
|
|
131
|
-
}
|
|
132
|
-
```
|
|
221
|
+
Never start `preview` by default. `deliver --open` is an opt-in one-shot handoff after commit. Full
|
|
222
|
+
receipt fields, coverage, sidecars, and exit behavior: `references/delivery-contract.md`.
|
|
133
223
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
### Dataflow
|
|
137
|
-
|
|
138
|
-
```json
|
|
139
|
-
{
|
|
140
|
-
"schema_version": 1,
|
|
141
|
-
"diagram_type": "dataflow",
|
|
142
|
-
"meta": { "title": "Product Analytics", "subtitle": "events to consumers", "output": "analytics.html" },
|
|
143
|
-
"stages": [ { "label": "Sources" }, { "label": "Ingest" }, { "label": "Store" } ],
|
|
144
|
-
"nodes": [
|
|
145
|
-
{ "id": "web", "type": "frontend", "label": "Web App", "stage": 0, "row": 0, "sublabel": "clickstream" },
|
|
146
|
-
{ "id": "kafka", "type": "messagebus", "label": "Kafka", "stage": 1, "row": 0, "tag": "accepted events" }
|
|
147
|
-
],
|
|
148
|
-
"flows": [
|
|
149
|
-
{ "from": "web", "to": "kafka", "label": "events", "classification": "PII touch", "variant": "emphasis" }
|
|
150
|
-
],
|
|
151
|
-
"cards": []
|
|
152
|
-
}
|
|
153
|
-
```
|
|
224
|
+
## Architecture Delta
|
|
154
225
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
### Lifecycle
|
|
158
|
-
|
|
159
|
-
```json
|
|
160
|
-
{
|
|
161
|
-
"schema_version": 1,
|
|
162
|
-
"diagram_type": "lifecycle",
|
|
163
|
-
"meta": { "title": "Agent Run Lifecycle", "subtitle": "states and terminal outcomes", "output": "agent-run.html" },
|
|
164
|
-
"lanes": [
|
|
165
|
-
{ "id": "main", "label": "Lifecycle phases" },
|
|
166
|
-
{ "id": "waiting", "label": "Interruptions" },
|
|
167
|
-
{ "id": "terminal", "label": "Terminal exits" }
|
|
168
|
-
],
|
|
169
|
-
"states": [
|
|
170
|
-
{ "id": "queued", "type": "start", "label": "Queued", "lane": "main", "col": 0, "step": "01" },
|
|
171
|
-
{ "id": "running", "type": "active", "label": "Executing", "lane": "main", "col": 2, "step": "02" },
|
|
172
|
-
{ "id": "approval", "type": "waiting", "label": "Needs Approval", "lane": "waiting", "col": 0 },
|
|
173
|
-
{ "id": "done", "type": "success", "label": "Completed", "lane": "terminal", "col": 2 }
|
|
174
|
-
],
|
|
175
|
-
"transitions": [
|
|
176
|
-
{ "from": "queued", "to": "running", "variant": "emphasis" },
|
|
177
|
-
{ "from": "running", "to": "approval", "label": "needs approval", "variant": "security", "fromSide": "bottom", "toSide": "right" },
|
|
178
|
-
{ "from": "running", "to": "done", "label": "success", "variant": "emphasis", "fromSide": "bottom", "toSide": "top" }
|
|
179
|
-
],
|
|
180
|
-
"cards": []
|
|
181
|
-
}
|
|
182
|
-
```
|
|
226
|
+
For design or PR review, compare two validated architecture snapshots as Before / Delta / After with
|
|
227
|
+
a machine receipt of exactly what was added, removed, changed, moved, and rerouted:
|
|
183
228
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
### Per-mode deep guidance
|
|
187
|
-
|
|
188
|
-
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.
|
|
189
|
-
|
|
190
|
-
## Architecture Mode
|
|
191
|
-
|
|
192
|
-
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.
|
|
193
|
-
|
|
194
|
-
```json
|
|
195
|
-
{
|
|
196
|
-
"schema_version": 1,
|
|
197
|
-
"diagram_type": "architecture",
|
|
198
|
-
"meta": { "title": "Sample Web App", "subtitle": "3-tier SaaS on AWS", "output": "web-app.html" },
|
|
199
|
-
"components": [
|
|
200
|
-
{ "id": "users", "type": "external", "label": "Users", "sublabel": "Browser", "pos": [40, 300] },
|
|
201
|
-
{ "id": "api", "type": "backend", "label": "API Server", "sublabel": "FastAPI :8000", "pos": [460, 300] },
|
|
202
|
-
{ "id": "db", "type": "database", "label": "PostgreSQL", "sublabel": ":5432", "pos": [680, 300] }
|
|
203
|
-
],
|
|
204
|
-
"boundaries": [
|
|
205
|
-
{ "kind": "region", "label": "AWS us-west-2", "wraps": ["api", "db"] }
|
|
206
|
-
],
|
|
207
|
-
"connections": [
|
|
208
|
-
{ "from": "users", "to": "api", "label": "HTTPS", "variant": "emphasis" },
|
|
209
|
-
{ "from": "api", "to": "db", "label": "SQL" }
|
|
210
|
-
],
|
|
211
|
-
"cards": []
|
|
212
|
-
}
|
|
229
|
+
```bash
|
|
230
|
+
.claude/skills/stacks-technical-diagrams/bin/diagrams compare architecture base.json head.json delta.html --receipt delta.receipt.json --json
|
|
213
231
|
```
|
|
214
232
|
|
|
215
|
-
|
|
233
|
+
Component identity is `components[].id`, relationship identity is `connections[].id` (required for
|
|
234
|
+
compare), and boundary identity is derived from `kind` + `label`. The delta reports authored facts
|
|
235
|
+
only; it infers no impact, risk, or merge safety.
|
|
216
236
|
|
|
217
|
-
|
|
237
|
+
## Brand marks
|
|
218
238
|
|
|
219
|
-
|
|
239
|
+
Brand identity is optional and explicit. When a node names a real product, look up a canonical
|
|
240
|
+
built-in ID from the bundled catalogue of 107 marks:
|
|
220
241
|
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
"layout": { "mode": "grid", "cols": 7, "origin": [40, 100], "gapX": 24, "gapY": 48, "cellW": 120, "cellH": 60 },
|
|
224
|
-
"components": [
|
|
225
|
-
{ "id": "agents", "type": "frontend", "label": "Agent Hosts", "row": 1, "col": 1 },
|
|
226
|
-
{ "id": "ir", "type": "messagebus", "label": "JSON IR", "row": 1, "col": 2 }
|
|
227
|
-
]
|
|
228
|
-
}
|
|
242
|
+
```bash
|
|
243
|
+
.claude/skills/stacks-technical-diagrams/bin/diagrams brands "postgres" --json
|
|
229
244
|
```
|
|
230
245
|
|
|
231
|
-
|
|
246
|
+
Never infer a brand from a vague role such as "database", and never let a badge replace the semantic
|
|
247
|
+
`type`, label, or relationship facts. `brands capture <url>` is the one command in this skill that
|
|
248
|
+
makes a network request: it is user-initiated, it pins the result by SHA-256, and `render`,
|
|
249
|
+
`validate`, `deliver`, and `compare` never perform an unpinned capture. See
|
|
250
|
+
`references/brand-marks.md`.
|
|
232
251
|
|
|
233
|
-
|
|
252
|
+
## Dependency-free and offline contract
|
|
234
253
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
254
|
+
Do not install packages or fetch runtime assets. Standalone validators for all five schemas are
|
|
255
|
+
checked in, the renderers use Bun's Node compatibility modules, and delivered HTML embeds its own
|
|
256
|
+
subsetted JetBrains Mono, so a page renders with no network access. Upstream's update-notifier
|
|
257
|
+
scripts are deliberately not vendored: this port is pinned by `metadata.source_commit` and is updated
|
|
258
|
+
by re-porting, never by a runtime download.
|
|
239
259
|
|
|
240
|
-
|
|
260
|
+
Verify the install with `diagrams doctor`, and generate a ready-to-open example with
|
|
261
|
+
`diagrams demo <output-directory>` before the first custom diagram.
|
|
241
262
|
|
|
242
|
-
|
|
263
|
+
## Deeper references
|
|
243
264
|
|
|
244
|
-
|
|
245
|
-
- **Grid placement** - optional `layout.mode: "grid"` with `row`/`col` per component (see above). Not dagre; fixed cell spacing only.
|
|
246
|
-
- **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.
|
|
247
|
-
- **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).
|
|
248
|
-
- 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.
|
|
265
|
+
Read one of these only when the fast path calls for it.
|
|
249
266
|
|
|
250
|
-
|
|
267
|
+
| Need | Read |
|
|
268
|
+
|---|---|
|
|
269
|
+
| Field enums, spacing math, geometry repair, repository evidence, placement | `references/authoring-contract.md` |
|
|
270
|
+
| Receipt fields, coverage, sidecars, exit behavior, preview, export receipts | `references/delivery-contract.md` |
|
|
271
|
+
| Share cards, route/reach cards, motion, stories, deep links, presentation | `references/viewer-runtime.md` |
|
|
272
|
+
| Brand catalogue rules and capture | `references/brand-marks.md`, `brand-marks/README.md` |
|
|
273
|
+
| Per-mode layout budgets, route presets, semantic types | `renderers/<mode>/README.md` |
|
|
274
|
+
| IR overview across all five modes | `schemas/README.md` |
|
|
251
275
|
|
|
252
|
-
|
|
276
|
+
## Hand-placed fallback (no Bun available)
|
|
253
277
|
|
|
254
|
-
|
|
278
|
+
When the CLI cannot run, copy `assets/template.html`, place SVG by hand using the design system
|
|
279
|
+
below, and run the self-review checklist before delivering.
|
|
255
280
|
|
|
256
|
-
The
|
|
281
|
+
**The cardinal rule: CSS classes, not inline colors.** The theme toggle switches CSS custom
|
|
282
|
+
properties, so `fill="rgba(...)"` or `stroke="#22d3ee"` will not follow the theme.
|
|
257
283
|
|
|
258
284
|
```svg
|
|
259
285
|
<rect x="X" y="Y" width="W" height="H" rx="6" class="c-mask"/>
|
|
@@ -262,29 +288,31 @@ The theme toggle works by switching CSS custom properties. Hardcoded `fill="rgba
|
|
|
262
288
|
<text x="CX" y="CY+16" class="t-muted" font-size="9" text-anchor="middle">FastAPI :8000</text>
|
|
263
289
|
```
|
|
264
290
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
### Hard layout rules
|
|
291
|
+
Component fills `c-frontend`, `c-backend`, `c-database`, `c-cloud`, `c-security`, `c-messagebus`,
|
|
292
|
+
`c-external`; text accents `t-<same>` plus `t-primary` / `t-muted` / `t-dim`. Arrows `a-default`,
|
|
293
|
+
`a-emphasis` (hot path), `a-security` (dashed), `a-dashed` (async), each with an explicit
|
|
294
|
+
`stroke-width` and a matching `marker-end="url(#arrowhead[-variant])"`. Boundaries:
|
|
295
|
+
`c-security-group` (dashed rose), `c-region` (dashed amber), `c-lane`. Typography inherits JetBrains
|
|
296
|
+
Mono from the SVG root: 11-12px component names, 9px sublabels, 8px annotations, 7px tiny labels.
|
|
272
297
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
- **Legend placement**: outside ALL boundary boxes, ≥20px below the lowest one; grow the viewBox if needed.
|
|
298
|
+
Hard layout rules: an opaque `c-mask` rect immediately before every styled `c-<type>` rect; all
|
|
299
|
+
arrows before all component rects in document order; at least 40px vertical gap between components;
|
|
300
|
+
boundary `y` = inner `y` - 30 and boundary `height` = inner `height` + 50 with the label baseline 18px
|
|
301
|
+
below the boundary top; the legend outside every boundary and at least 20px below the lowest one.
|
|
278
302
|
|
|
279
|
-
|
|
303
|
+
Self-review before delivering:
|
|
280
304
|
|
|
281
|
-
1. `grep -E 'fill="(#|rgb)|stroke="(#|rgb)' out.html` inside the SVG returns nothing
|
|
305
|
+
1. `grep -E 'fill="(#|rgb)|stroke="(#|rgb)' out.html` inside the SVG returns nothing but the
|
|
306
|
+
template's own defs.
|
|
282
307
|
2. Every `c-<type>` rect has an identical-geometry `c-mask` rect immediately before it.
|
|
283
|
-
3. All
|
|
284
|
-
4.
|
|
308
|
+
3. All arrows appear before all component rects in document order.
|
|
309
|
+
4. max(y + height) over all SVG elements is at least 20px inside the viewBox height; same for x.
|
|
285
310
|
5. Legend y is below every boundary's y + height.
|
|
286
|
-
6. The `.toolbar`, `<script>` blocks, and `:root` / `[data-theme]` CSS are untouched
|
|
311
|
+
6. The `.toolbar`, `<script>` blocks, and `:root` / `[data-theme]` CSS are untouched. They are the
|
|
312
|
+
theme toggle, viewer, and export menu.
|
|
287
313
|
|
|
288
314
|
## Output
|
|
289
315
|
|
|
290
|
-
|
|
316
|
+
Report the checked HTML path, the diagram type, the validation summary, the specification and
|
|
317
|
+
artifact receipt, the browser-evidence status, and a truthful visual-review status. Never claim
|
|
318
|
+
success for a non-zero command, and never claim a visual inspection you did not perform.
|