@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.
Files changed (74) hide show
  1. package/ai/skills/stacks-cms/SKILL.md +4 -4
  2. package/ai/skills/stacks-config/SKILL.md +1 -1
  3. package/ai/skills/stacks-technical-diagrams/LICENSE +1 -1
  4. package/ai/skills/stacks-technical-diagrams/SKILL.md +257 -229
  5. package/ai/skills/stacks-technical-diagrams/THIRD_PARTY_NOTICES.md +69 -0
  6. package/ai/skills/stacks-technical-diagrams/assets/JetBrainsMono-OFL.txt +93 -0
  7. package/ai/skills/stacks-technical-diagrams/assets/template.html +14588 -929
  8. package/ai/skills/stacks-technical-diagrams/bin/diagrams +10 -0
  9. package/ai/skills/stacks-technical-diagrams/bin/open-artifact.mjs +86 -0
  10. package/ai/skills/stacks-technical-diagrams/bin/preview.mjs +654 -0
  11. package/ai/skills/stacks-technical-diagrams/bin/technical-diagrams.mjs +1898 -89
  12. package/ai/skills/stacks-technical-diagrams/bin/visual-check.mjs +829 -0
  13. package/ai/skills/stacks-technical-diagrams/brand-marks/README.md +31 -0
  14. package/ai/skills/stacks-technical-diagrams/brand-marks/catalog.json +131 -0
  15. package/ai/skills/stacks-technical-diagrams/delta/architecture-delta.mjs +1221 -0
  16. package/ai/skills/stacks-technical-diagrams/examples/agent-run.lifecycle.json +18 -22
  17. package/ai/skills/stacks-technical-diagrams/examples/agent-tool-call.workflow.json +58 -52
  18. package/ai/skills/stacks-technical-diagrams/examples/async-job-roundtrip.sequence.json +61 -0
  19. package/ai/skills/stacks-technical-diagrams/examples/brand-aware-delivery.architecture.json +47 -0
  20. package/ai/skills/stacks-technical-diagrams/examples/cache-miss-request.sequence.json +30 -23
  21. package/ai/skills/stacks-technical-diagrams/examples/checkout-platform.base.architecture.json +31 -0
  22. package/ai/skills/stacks-technical-diagrams/examples/checkout-platform.head.architecture.json +31 -0
  23. package/ai/skills/stacks-technical-diagrams/examples/deployment-release.lifecycle.json +49 -0
  24. package/ai/skills/stacks-technical-diagrams/examples/event-stream.dataflow.json +57 -0
  25. package/ai/skills/stacks-technical-diagrams/examples/incident-response.workflow.json +64 -0
  26. package/ai/skills/stacks-technical-diagrams/examples/product-analytics.dataflow.json +22 -16
  27. package/ai/skills/stacks-technical-diagrams/examples/production-deployment.architecture.json +71 -0
  28. package/ai/skills/stacks-technical-diagrams/examples/release-delivery.workflow.json +62 -0
  29. package/ai/skills/stacks-technical-diagrams/examples/web-app.architecture.json +16 -11
  30. package/ai/skills/stacks-technical-diagrams/migrations/workflow-v2.mjs +279 -0
  31. package/ai/skills/stacks-technical-diagrams/recipes/scenarios.mjs +391 -0
  32. package/ai/skills/stacks-technical-diagrams/references/authoring-contract.md +243 -0
  33. package/ai/skills/stacks-technical-diagrams/references/brand-marks.md +65 -0
  34. package/ai/skills/stacks-technical-diagrams/references/delivery-contract.md +120 -0
  35. package/ai/skills/stacks-technical-diagrams/references/viewer-runtime.md +45 -0
  36. package/ai/skills/stacks-technical-diagrams/renderers/architecture/render-architecture.mjs +780 -73
  37. package/ai/skills/stacks-technical-diagrams/renderers/dataflow/README.md +25 -3
  38. package/ai/skills/stacks-technical-diagrams/renderers/dataflow/render-dataflow.mjs +240 -52
  39. package/ai/skills/stacks-technical-diagrams/renderers/lifecycle/README.md +31 -7
  40. package/ai/skills/stacks-technical-diagrams/renderers/lifecycle/render-lifecycle.mjs +227 -50
  41. package/ai/skills/stacks-technical-diagrams/renderers/sequence/README.md +36 -6
  42. package/ai/skills/stacks-technical-diagrams/renderers/sequence/render-sequence.mjs +270 -63
  43. package/ai/skills/stacks-technical-diagrams/renderers/shared/brand-marks.mjs +563 -0
  44. package/ai/skills/stacks-technical-diagrams/renderers/shared/bun-runtime.mjs +20 -0
  45. package/ai/skills/stacks-technical-diagrams/renderers/shared/cli.mjs +186 -10
  46. package/ai/skills/stacks-technical-diagrams/renderers/shared/desktop-readability.mjs +26 -0
  47. package/ai/skills/stacks-technical-diagrams/renderers/shared/diagnostics.mjs +127 -0
  48. package/ai/skills/stacks-technical-diagrams/renderers/shared/engineering-profiles.mjs +157 -0
  49. package/ai/skills/stacks-technical-diagrams/renderers/shared/generated-brand-marks.mjs +2003 -0
  50. package/ai/skills/stacks-technical-diagrams/renderers/shared/generated-validators.mjs +3 -3
  51. package/ai/skills/stacks-technical-diagrams/renderers/shared/geometry.mjs +1195 -2
  52. package/ai/skills/stacks-technical-diagrams/renderers/shared/i18n.mjs +595 -0
  53. package/ai/skills/stacks-technical-diagrams/renderers/shared/legend.mjs +217 -0
  54. package/ai/skills/stacks-technical-diagrams/renderers/shared/output-path.mjs +340 -0
  55. package/ai/skills/stacks-technical-diagrams/renderers/shared/repository-evidence.mjs +238 -0
  56. package/ai/skills/stacks-technical-diagrams/renderers/shared/repository-location.mjs +58 -0
  57. package/ai/skills/stacks-technical-diagrams/renderers/shared/text-fit.mjs +49 -0
  58. package/ai/skills/stacks-technical-diagrams/renderers/shared/utils.mjs +163 -19
  59. package/ai/skills/stacks-technical-diagrams/renderers/shared/validator.mjs +51 -5
  60. package/ai/skills/stacks-technical-diagrams/renderers/workflow/README.md +137 -17
  61. package/ai/skills/stacks-technical-diagrams/renderers/workflow/render-workflow.mjs +24 -470
  62. package/ai/skills/stacks-technical-diagrams/renderers/workflow/workflow-compiler.mjs +4400 -0
  63. package/ai/skills/stacks-technical-diagrams/renderers/workflow/workflow-migration-geometry.mjs +144 -0
  64. package/ai/skills/stacks-technical-diagrams/schemas/README.md +154 -11
  65. package/ai/skills/stacks-technical-diagrams/schemas/architecture.schema.json +61 -4
  66. package/ai/skills/stacks-technical-diagrams/schemas/common.schema.json +72 -0
  67. package/ai/skills/stacks-technical-diagrams/schemas/dataflow.schema.json +40 -18
  68. package/ai/skills/stacks-technical-diagrams/schemas/lifecycle.schema.json +43 -18
  69. package/ai/skills/stacks-technical-diagrams/schemas/sequence.schema.json +41 -4
  70. package/ai/skills/stacks-technical-diagrams/schemas/workflow.schema.json +97 -1
  71. package/ai/skills/stacks-technical-diagrams/scripts/check-render-output.mjs +551 -12
  72. package/ai/skills/stacks-technical-diagrams/scripts/render-examples.mjs +3 -4
  73. package/ide/vscode/package.json +1 -1
  74. 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, enableComments/RSS/sitemap |
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 (original "architecture-diagram-generator")
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, dependency-free architecture, workflow, sequence, data-flow, and lifecycle diagrams for Stacks applications as standalone HTML with inline SVG, dark/light themes, and PNG, JPEG, WebP, and SVG export. 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.
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.10.0"
8
- source_commit: 73f769d2e97c7fb54b74bebb276c1987db278c3f
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
- Create professional technical diagrams as self-contained HTML files with inline SVG, a theme toggle, and a built-in image/SVG export menu.
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 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.
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 visual system from [Archify](https://github.com/tt-a1i/archify) 2.10.0 by tt-a1i under the MIT license. Archify is itself a fork and rewrite of Cocoon AI's `architecture-diagram-generator` 1.0. Preserve `LICENSE` when redistributing this skill or substantial portions of its source.
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
- ## Dependency-free contract
30
+ ## Running the CLI
23
31
 
24
- Do not install packages or fetch runtime assets. Use Bun and the bundled source only. Standalone validators for all five JSON schemas are checked in, the renderer uses Bun's built-in Node compatibility modules, and generated HTML uses system font fallbacks with no network requests.
32
+ Every command below is one launcher invocation from the Stacks project root:
25
33
 
26
- Run `bun --config=storage/framework/defaults/ai/skills/stacks-technical-diagrams/bunfig.toml --no-env-file storage/framework/defaults/ai/skills/stacks-technical-diagrams/bin/technical-diagrams.mjs doctor` from the Stacks project root to verify the skill. Run `bun --config=storage/framework/defaults/ai/skills/stacks-technical-diagrams/bunfig.toml --no-env-file storage/framework/defaults/ai/skills/stacks-technical-diagrams/bin/technical-diagrams.mjs demo [output-directory]` to generate a ready-to-open example before creating the first custom diagram.
27
-
28
- ## Stacks repository workflow
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
- ## Renderer Modes (architecture / workflow / sequence / dataflow / lifecycle)
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
- All five modes follow the same loop:
88
+ ## Stacks repository workflow
78
89
 
79
- 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.
80
- 2. Write `<name>.<type>.json`.
81
- 3. Render: `bun --config=storage/framework/defaults/ai/skills/stacks-technical-diagrams/bunfig.toml --no-env-file storage/framework/defaults/ai/skills/stacks-technical-diagrams/bin/technical-diagrams.mjs render <type> <input>.json <output>.html`.
82
- 4. Validate the generated artifact: `bun --config=storage/framework/defaults/ai/skills/stacks-technical-diagrams/bunfig.toml --no-env-file storage/framework/defaults/ai/skills/stacks-technical-diagrams/bin/technical-diagrams.mjs validate <type> <input>.json --json`, or check an existing HTML file with `bun --config=storage/framework/defaults/ai/skills/stacks-technical-diagrams/bunfig.toml --no-env-file storage/framework/defaults/ai/skills/stacks-technical-diagrams/bin/technical-diagrams.mjs check <output>.html`. This catches malformed SVG output, non-finite SVG values, two-point diagonal arrows, and arrows crossing the legend.
83
- 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.
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
- 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.
203
+ ```bash
204
+ .claude/skills/stacks-technical-diagrams/bin/diagrams visual-check <output.html> --json
205
+ ```
86
206
 
87
- 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.
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
- ### Workflow
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
- ```json
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
- **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.
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
- **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".
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
- **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.
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
- **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.
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
- Render: `bun --config=storage/framework/defaults/ai/skills/stacks-technical-diagrams/bunfig.toml --no-env-file storage/framework/defaults/ai/skills/stacks-technical-diagrams/bin/technical-diagrams.mjs render architecture <input>.json <output>.html`.
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
- **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).
237
+ ## Brand marks
218
238
 
219
- **Grid placement (#8)** - when manual coordinates are painful, set semantic cells instead of doing arithmetic:
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
- ```json
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
- `pos` still wins when present and overrides one cell. This is **not** auto-layout. Spacing is fixed cell math.
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
- **Inspect layout (#9)** - after editing JSON, dump computed boxes without opening HTML:
252
+ ## Dependency-free and offline contract
234
253
 
235
- ```bash
236
- bun --config=storage/framework/defaults/ai/skills/stacks-technical-diagrams/bunfig.toml --no-env-file storage/framework/defaults/ai/skills/stacks-technical-diagrams/bin/technical-diagrams.mjs inspect architecture my.architecture.json
237
- # or: bun --config=storage/framework/defaults/ai/skills/stacks-technical-diagrams/bunfig.toml --no-env-file storage/framework/defaults/ai/skills/stacks-technical-diagrams/bin/technical-diagrams.mjs validate architecture my.architecture.json --layout-json
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
- Output includes component rects, boundaries, connection point paths, and label positions.
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
- **The renderer does the mechanical work that used to be hand-tuned**, so you only choose coordinates and meaning:
263
+ ## Deeper references
243
264
 
244
- - **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).
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
- ### Hand-placed fallback (no renderer available)
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
- When Bun cannot run, copy `assets/template.html` and place SVG by hand. Study the worked diagram inside the template for coordinate idioms, follow the design system below, and run the self-review checklist before delivering.
276
+ ## Hand-placed fallback (no Bun available)
253
277
 
254
- ### The Cardinal Rule: CSS classes, not inline colors
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 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:
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
- ### Design system
266
-
267
- 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).
268
-
269
- Typography inherits JetBrains Mono from the SVG root. Sizes: 11-12px component names, 9px sublabels, 8px annotations, 7px tiny labels.
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
- - **Two-rect pattern everywhere**: opaque `c-mask` rect first, styled `c-<type>` rect on top - semi-transparent fills otherwise let arrows bleed through.
274
- - **Arrows before components** in document order (SVG paints in order; arrows must sit behind boxes).
275
- - **Vertical stacking**: ≥40px gap between components; inline connectors (message buses, 20px tall) live inside the gap, never overlapping boxes.
276
- - **Boundary padding**: boundary `y` = inner `y` − 30, boundary `height` = inner `height` + 50, label baseline 18px below the boundary top.
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
- ### Self-review checklist (run before delivering)
303
+ Self-review before delivering:
280
304
 
281
- 1. `grep -E 'fill="(#|rgb)|stroke="(#|rgb)' out.html` inside the SVG returns nothing except the template's own defs (Cardinal Rule).
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 `<line>`/`<path>` arrows appear before all component rects in document order.
284
- 4. Compute max(y + height) over all SVG elements: viewBox height must exceed it by ≥20px; same for x/width.
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 - they ARE the theme toggle and export menu.
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
- A single self-contained `.html`: embedded CSS with local system font fallbacks, inline SVG, and embedded theme and export JavaScript. It renders directly in any modern browser without network access. Raster exports render natively at up to 4× the viewBox, with large diagrams stepping down to stay within canvas limits. SVG downloads are dual-theme, self-contained, and follow the host's `prefers-color-scheme` with an optional `svg[data-theme="..."]` override.
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.