@alfacapital-tech/c4builder 0.4.0 → 0.5.0
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/README.MD +69 -615
- package/dist/cli/commands/check.js +43 -26
- package/dist/cli/commands/help.js +5 -2
- package/dist/cli/commands/jre.js +6 -6
- package/dist/cli/commands/list.js +4 -1
- package/dist/cli/commands/new.js +6 -6
- package/dist/cli/commands/site.js +3 -2
- package/dist/cli/dispatch.js +38 -18
- package/dist/cli/wizard/collect.js +16 -10
- package/dist/config/defaults.js +1 -0
- package/dist/config/options.js +1 -1
- package/dist/config/schema.js +5 -2
- package/dist/core/build.js +15 -6
- package/dist/core/compose/docsify.template.js +0 -1
- package/dist/core/compose/markdown.js +85 -19
- package/dist/core/plugins/hooks.js +1 -1
- package/dist/core/plugins/load.js +6 -6
- package/dist/core/plugins/source.js +6 -6
- package/dist/core/plugins/tree.js +5 -5
- package/dist/core/render/bpmnrenderer.js +522 -0
- package/dist/core/render/d2renderer.js +19 -19
- package/dist/core/render/diagrams.js +64 -45
- package/dist/core/render/jre.js +14 -14
- package/dist/core/render/pngraster.js +4 -4
- package/dist/{plugins/openspec → core/scan}/fences.js +11 -10
- package/dist/core/scan/tree.js +37 -14
- package/dist/plugins/openapi/index.js +17 -7
- package/dist/plugins/openspec/index.js +1 -1
- package/dist/plugins/openspec/render.js +5 -2
- package/dist/util/archive.js +1 -1
- package/dist/util/http.js +3 -3
- package/dist/util/lock.js +3 -3
- package/dist/util/paths.js +1 -1
- package/package.json +9 -4
- package/template/AGENTS.md +52 -0
- package/template/readme.md +3 -3
- package/template/src/5 BPMN Example/account-opening.bpmn +69 -0
- package/template/src/5 BPMN Example/account-opening.md +7 -0
- package/dist/util/glob.js +0 -69
package/README.MD
CHANGED
|
@@ -1,649 +1,103 @@
|
|
|
1
|
-
|
|
1
|
+
**[Документация на русском](https://alfacapital-tech.github.io/C4-Builder/ru/)** · [English documentation](https://alfacapital-tech.github.io/C4-Builder/en/) · [Site](https://alfacapital-tech.github.io/C4-Builder/)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# C4-Builder
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Architecture as code that an agent writes, checks and reads.**
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
C4-Builder is a CLI that builds a folder of markdown files and [PlantUML](https://plantuml.com/),
|
|
8
|
+
[D2](https://d2lang.com/) or [BPMN](https://www.bpmn.org/) diagrams into documentation: a [docsify](https://docsify.js.org/)
|
|
9
|
+
site, a markdown file per folder, or a single file. Folders follow the
|
|
10
|
+
[C4 model](https://c4model.com/) (system → container → component), and git keeps the history of
|
|
11
|
+
architecture decisions next to the code.
|
|
8
12
|
|
|
9
|
-
|
|
13
|
+
## Why this fork
|
|
10
14
|
|
|
11
|
-
-
|
|
15
|
+
The original [C4-Builder](https://github.com/adrianvlupu/C4-Builder) by Adrian Victor Lupu has not
|
|
16
|
+
been developed since March 2024. At Alfa-Capital it builds an architecture repository of more
|
|
17
|
+
than a hundred diagrams, so we continue it as a maintained fork, adapted to working with AI agents:
|
|
12
18
|
|
|
13
|
-
-
|
|
19
|
+
- **Deterministic offline rendering.** The PlantUML jar, the diagram font and the engines ship
|
|
20
|
+
with the package; layout is computed by PlantUML's built-in Smetana engine, no Graphviz. The
|
|
21
|
+
same sources produce the same SVG on a laptop, in CI and in Docker, with no network access.
|
|
22
|
+
- **`c4builder check`** validates individual `.puml`/`.iuml`/`.d2`/`.bpmn` files with the build's own
|
|
23
|
+
engine and returns an exit code and the error line — fast feedback for agents, pre-commit
|
|
24
|
+
hooks and CI.
|
|
25
|
+
- **Plugins.** `openspec` publishes an [OpenSpec](https://github.com/Fission-AI/OpenSpec) store
|
|
26
|
+
(specs and changes) as a site section; `openapi` renders service contracts as offline
|
|
27
|
+
swagger-ui pages.
|
|
28
|
+
- **D2** as a second diagram engine, deterministic **PNG** via resvg, and **optional Java**:
|
|
29
|
+
without a system Java, c4builder downloads a private JRE.
|
|
30
|
+
- **BPMN** processes written as BPMN 2.0 XML without coordinates: the build validates the model
|
|
31
|
+
and lays it out with horizontal pools and lanes.
|
|
32
|
+
- **Maintained.** TypeScript, golden rendering snapshots, CI on every pull request, releases to
|
|
33
|
+
npm and GHCR. The PDF output of the original was removed.
|
|
14
34
|
|
|
15
|
-
|
|
35
|
+
## Quick start
|
|
16
36
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
- [Docsify](https://docsify.js.org/) creates a single page site based on markdown files.
|
|
20
|
-
|
|
21
|
-
- [vscode-plantuml](https://github.com/qjebbs/vscode-plantuml) plugin for visual studio code to view diagrams at design time
|
|
22
|
-
|
|
23
|
-
I strongly encourage people to check them out first but if you want to dive right in, the _new project_ template should be easy to understand and edit.
|
|
24
|
-
|
|
25
|
-
<!--  -->
|
|
26
|
-
|
|
27
|
-

|
|
28
|
-
|
|
29
|
-
# Getting started
|
|
30
|
-
|
|
31
|
-
`npm i -g @alfacapital-tech/c4builder`
|
|
32
|
-
|
|
33
|
-
`npm install` (no tag) always installs the latest stable release. Release candidates are
|
|
34
|
-
opt-in only — see [Installing a release candidate](#installing-a-release-candidate).
|
|
35
|
-
|
|
36
|
-
**Requirements:** Node.js ≥ 20.19. Local diagram generation needs Java 17+: a system
|
|
37
|
-
`java` (`JAVA_HOME`/`PATH`) is used when present, otherwise c4builder downloads a private
|
|
38
|
-
JRE into its cache automatically (`c4builder jre install` pre-warms it, `jre info` shows
|
|
39
|
-
what would be used). Graphviz is **not** required — layout is computed by PlantUML's
|
|
40
|
-
built-in Java engine (Smetana). The PlantUML jar and the diagram font are bundled.
|
|
41
|
-
|
|
42
|
-
With `diagramFormat: png`, diagrams are produced by rasterizing their SVG with
|
|
43
|
-
[`@resvg/resvg-js`](https://github.com/thx/resvg-js) (a bundled dependency, prebuilt
|
|
44
|
-
native binary, no browser). This gives a single deterministic PNG for both PlantUML and
|
|
45
|
-
D2, using the bundled font. ditaa diagrams stay native PlantUML PNG.
|
|
46
|
-
|
|
47
|
-
**Fonts.** Diagrams use the bundled Nimbus Sans (Helvetica metrics, Cyrillic and Greek —
|
|
48
|
-
see `vendor/fonts/README.md`), so diagram geometry is identical on any machine.
|
|
49
|
-
`useSystemFonts: true` in `.c4builder` (or `--system-fonts` for one run) renders with the
|
|
50
|
-
machine's fonts instead — machine-dependent by design.
|
|
51
|
-
|
|
52
|
-
The easiest way to get started is with the _new project_ template.
|
|
53
|
-
|
|
54
|
-

|
|
55
|
-
|
|
56
|
-
```bash
|
|
57
|
-
c4builder new
|
|
58
|
-
cd project
|
|
59
|
-
c4builder
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
A sample project is available at [C4Builder-Demo](https://github.com/adrianvlupu/C4Builder-Demo/tree/master/docs).
|
|
63
|
-
|
|
64
|
-
## Available Commands
|
|
37
|
+
Requires Node.js ≥ 22.17. Java 17+ is optional.
|
|
65
38
|
|
|
66
39
|
```bash
|
|
67
|
-
|
|
68
|
-
Usage: index [options]
|
|
40
|
+
npm i -g @alfacapital-tech/c4builder
|
|
69
41
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
-y, --yes non-interactive --new: defaults, no prompts
|
|
75
|
-
(requires --name)
|
|
76
|
-
--force for `jre install`: force JRE download even if
|
|
77
|
-
system java is present
|
|
78
|
-
--config change configuration for the current directory
|
|
79
|
-
-c, --config-file <.c4builder> set the configuration file relative path
|
|
80
|
-
--list display the current configuration
|
|
81
|
-
--reset clear all configuration
|
|
82
|
-
--site serve the generated site
|
|
83
|
-
-w, --watch watch for changes and rebuild
|
|
84
|
-
-o, --open open the generated site in the browser (with
|
|
85
|
-
--site)
|
|
86
|
-
--docs a brief explanation for the available
|
|
87
|
-
configuration options
|
|
88
|
-
--system-fonts render with system fonts instead of the
|
|
89
|
-
bundled one (not deterministic)
|
|
90
|
-
-p, --port <n> port used for serving the generated site
|
|
91
|
-
-h, --help display help for command
|
|
42
|
+
c4builder --new --name demo -y # project from the template, full config, no prompts
|
|
43
|
+
cd demo
|
|
44
|
+
c4builder # build into docs/
|
|
45
|
+
c4builder --site -w # live preview at http://localhost:3000
|
|
92
46
|
```
|
|
93
47
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
is accepted as a positional subcommand too, equivalent to `--site`.
|
|
48
|
+
Since 0.5.0, `c4builder new` and `c4builder config` work too (0.4.0 has only the flags).
|
|
49
|
+
Without `-y`, c4builder asks for the project name and the first build runs the setup wizard.
|
|
97
50
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
`c4builder check <file...>` validates individual `.puml` / `.iuml` / `.d2` files with the
|
|
101
|
-
same engines the build uses (bundled PlantUML jar + system/managed Java, bundled D2) —
|
|
102
|
-
no project or `.c4builder` needed, nothing is written. Handy for pre-commit hooks and CI:
|
|
103
|
-
exit code 0 when every file compiles, 1 otherwise; errors are printed as
|
|
104
|
-
`✗ file: line N: <engine message>`.
|
|
51
|
+
The agent loop — edit a diagram, check it, look at the result:
|
|
105
52
|
|
|
106
53
|
```bash
|
|
107
|
-
c4builder check src/
|
|
54
|
+
c4builder check src/context.puml # exit code 0 or 1, "✗ file: line N: message" on error
|
|
55
|
+
c4builder --site -w # rebuilds and reloads the browser on every save
|
|
108
56
|
```
|
|
109
57
|
|
|
110
|
-
|
|
111
|
-
|
|
58
|
+
For agents: `npx skills add AlfaCapital-Tech/C4-Builder/skills` installs the skills, and
|
|
59
|
+
`"generateLLMS": true` adds `llms.txt` / `llms-full.txt` (diagram sources included) to the site.
|
|
112
60
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
```bash
|
|
116
|
-
#!/bin/sh
|
|
117
|
-
files=$(git diff --cached --name-only --diff-filter=ACM -- '*.puml' '*.iuml' '*.d2')
|
|
118
|
-
[ -z "$files" ] || exec c4builder check $files
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
By default, running `c4builder` will attempt to build the project.
|
|
122
|
-
|
|
123
|
-
If no configuration was set it will ask for it and then do the actual build. Running just `c4builder` after a configuration will no longer show the wizard.
|
|
124
|
-
|
|
125
|
-
To change the configuration after building for the first time just run `c4builder config`. The default will be the configuration set previously so you can just edit the options you are interested in.
|
|
126
|
-
|
|
127
|
-
## The project
|
|
128
|
-
|
|
129
|
-
The project consists of two main folders. The **source** folder and the **destination** folder.
|
|
130
|
-
|
|
131
|
-
Following the C4 model, folders inside the **source** represent Systems/Containers/Components or any other additional type of information regarding the software.
|
|
132
|
-
|
|
133
|
-
```bash
|
|
134
|
-
│ .gitignore
|
|
135
|
-
│ README.MD
|
|
136
|
-
├───docs # destination folder
|
|
137
|
-
└───src # source folder
|
|
138
|
-
│ context.md
|
|
139
|
-
│ context.puml
|
|
140
|
-
└───Internet Banking System
|
|
141
|
-
│ system.puml
|
|
142
|
-
│ system.md
|
|
143
|
-
├───API Application
|
|
144
|
-
│ container.puml
|
|
145
|
-
│ container.md
|
|
146
|
-
└───Single Page Application
|
|
147
|
-
│ container.puml
|
|
148
|
-
│ container.md
|
|
149
|
-
└───Additional Information
|
|
150
|
-
additionalDetails.md
|
|
151
|
-
class.puml
|
|
152
|
-
sequence.puml
|
|
153
|
-
class.1.md
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
The **destination** folder is automatically generated by the **build** process and can have various formats. The folder can provide a drill down style view of the Systems/Containers/Components in different ways. Either by pushing it as a site to gitpages or using it as a navigable markdown directly in the repository.
|
|
157
|
-
|
|
158
|
-
## The build
|
|
159
|
-
|
|
160
|
-
The **build** process consists of parsing the folder structure and merging together all the information found in the markdown files and diagrams into a single file per folder.
|
|
161
|
-
|
|
162
|
-
The basic navigation, table of contents, local generation of images and their inclusion in the end documentation is automatically handled.
|
|
163
|
-
|
|
164
|
-
c4builder comes with a wizard for managing configuration for each project folder.
|
|
165
|
-
|
|
166
|
-

|
|
167
|
-
|
|
168
|
-
> NOTE
|
|
169
|
-
>
|
|
170
|
-
> Files starting with \_ will be ignored during the build process
|
|
171
|
-
|
|
172
|
-
**Diagrams can be placed at arbitrary positions by adding them to the markdown file like this: ``**
|
|
173
|
-
|
|
174
|
-
### D2 diagrams (second render backend)
|
|
175
|
-
|
|
176
|
-
Besides PlantUML (`.puml`), c4builder renders [D2](https://d2lang.com) diagrams
|
|
177
|
-
(`.d2`). The backend is chosen by file extension — `.puml` → PlantUML, `.d2` → D2
|
|
178
|
-
(WASM → SVG, no external binaries) — and both can live side by side in the same
|
|
179
|
-
project. Reference a `.d2` from markdown exactly like a `.puml`:
|
|
180
|
-
``.
|
|
181
|
-
|
|
182
|
-
The D2 engine is an **optional dependency** (`@terrastruct/d2`, ~60 MB) loaded
|
|
183
|
-
lazily only when the project actually contains a `.d2` file. Install it once:
|
|
184
|
-
|
|
185
|
-
```bash
|
|
186
|
-
npm install @terrastruct/d2
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
If a `.d2` is present but the package is missing, the build stops with an explicit
|
|
190
|
-
install hint instead of a cryptic module error.
|
|
191
|
-
|
|
192
|
-
**Imports and shared styles.** D2 [imports](https://d2lang.com/tour/imports)
|
|
193
|
-
(`@file` / spread `...@file`) let you factor reusable classes and vars into a shared
|
|
194
|
-
`.d2` — the D2 counterpart of PlantUML's `.iuml`. c4builder resolves the import graph
|
|
195
|
-
itself and feeds it to the engine, so no network access is needed. Prefix a shared
|
|
196
|
-
library file with `_` (e.g. `_c4lib.d2`) so it is not rendered as a standalone
|
|
197
|
-
diagram — like every `_`-prefixed file it is skipped by the build, yet it is still
|
|
198
|
-
resolved when imported (`...@../_c4lib`). Editing an imported file invalidates the
|
|
199
|
-
cache of every diagram that imports it. See the demo project's
|
|
200
|
-
`4 D2 Example/landscape.d2` importing `...@../_c4lib`.
|
|
201
|
-
|
|
202
|
-
**Layout.** The `d2Layout` config option selects the layout engine (`dagre`, the
|
|
203
|
-
default, or `elk`). The golden test pins a specific engine for reproducibility.
|
|
204
|
-
|
|
205
|
-
## The output
|
|
206
|
-
|
|
207
|
-
Using the configuration wizard you can choose any combination of outputs. By default all are enabled.
|
|
208
|
-
|
|
209
|
-
The output should have the same folder structure as the **source**. Each `.md` file inherits all the contents from the source `.md` files in that folder and appends either a link or the actual diagram images at the bottom/top of the file.
|
|
210
|
-
|
|
211
|
-
```bash
|
|
212
|
-
│ .gitignore
|
|
213
|
-
│ README.MD
|
|
214
|
-
├───docs
|
|
215
|
-
│ │ README.md
|
|
216
|
-
│ └───Internet Banking System
|
|
217
|
-
│ │ README.md
|
|
218
|
-
│ ├───API Application
|
|
219
|
-
│ │ README.md
|
|
220
|
-
│ └───Single Page Application
|
|
221
|
-
│ │ README.md
|
|
222
|
-
│ └───Additional Diagrams
|
|
223
|
-
│ README.md
|
|
224
|
-
└───src
|
|
225
|
-
│ ...
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
### Collection of markdowns with navigation
|
|
229
|
-
|
|
230
|
-
The generated markdown files can be pushed to git and viewed directly as a readme.
|
|
231
|
-
|
|
232
|
-

|
|
233
|
-
|
|
234
|
-
#### Options:
|
|
235
|
-
|
|
236
|
-
- basic navigation
|
|
237
|
-
|
|
238
|
-
The basic navigation comes in the form of a menu providing a link to the parent and descendants.
|
|
239
|
-
|
|
240
|
-

|
|
241
|
-
|
|
242
|
-
- table of contents (default)
|
|
243
|
-
|
|
244
|
-
The table navigation always shows all entities and bolds the current one
|
|
245
|
-
|
|
246
|
-

|
|
247
|
-
|
|
248
|
-
### Single markdown file
|
|
249
|
-
|
|
250
|
-
Outputs into a single file containing all entities. It includes a table of contents and a 'go to top' link after each section.
|
|
251
|
-
|
|
252
|
-
The generated markdown file makes for an easy single page readme for the repository.
|
|
253
|
-
|
|
254
|
-

|
|
255
|
-
|
|
256
|
-
### Docsify site with a sidebar
|
|
257
|
-
|
|
258
|
-
After choosing to generate a docsify site, it can be viewed locally by running `c4builder --site` and accessing `http://localhost:3000`;
|
|
259
|
-
|
|
260
|
-
The site is minimalistic including only a sidebar with the System/Container/Components hierarchy.
|
|
261
|
-
|
|
262
|
-
The sidebar is generated manually so that it only contains the main entities defined in the project in a hierarchical way.
|
|
263
|
-
|
|
264
|
-

|
|
265
|
-
|
|
266
|
-
By going to the github repository settings and enabling GitHub pages the site be pushed with ease and provide an overview to all people involved in the project.
|
|
267
|
-
|
|
268
|
-

|
|
269
|
-
|
|
270
|
-
### Generate diagrams locally
|
|
271
|
-
|
|
272
|
-
By default this option is disabled. The output will contain image files generated using the plantuml server.
|
|
273
|
-
|
|
274
|
-
```md
|
|
275
|
-

|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
If enabled, all images will be generated using the local copy of plantuml (via a
|
|
279
|
-
direct `java` call, Smetana layout — no graphviz needed) and will get added to the
|
|
280
|
-
**destination** folder.
|
|
281
|
-
|
|
282
|
-
### Replace diagrams with link
|
|
283
|
-
|
|
284
|
-
By default this is disabled. If enabled, the output will no longer include the actual diagrams but a link to the image file.
|
|
285
|
-
|
|
286
|
-
### Include breadcrumbs
|
|
287
|
-
|
|
288
|
-
The current entity structure is inserted after the header
|
|
289
|
-
|
|
290
|
-
## Plugins
|
|
291
|
-
|
|
292
|
-
Plugins extend the build with content from outside `rootFolder` (virtual pages that go through
|
|
293
|
-
the regular pipeline: sidebar, search, `generateMD`, complete markdown, local diagram render)
|
|
294
|
-
and with site assets. They are listed in `.c4builder` under `plugins` — either `"name"` or
|
|
295
|
-
`["name", { ...options }]`:
|
|
296
|
-
|
|
297
|
-
```json
|
|
298
|
-
{
|
|
299
|
-
"plugins": [
|
|
300
|
-
"openspec",
|
|
301
|
-
["openapi", { "dir": "../contracts", "glob": "*/openapi.yaml" }]
|
|
302
|
-
]
|
|
303
|
-
}
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
A plugin identifier resolves in this order: a built-in name (`openspec`, `openapi`) → a local
|
|
307
|
-
ESM module (`./plugins/my.mjs`, `../shared/plugin.mjs`, absolute path) → an npm package resolved
|
|
308
|
-
from the project directory. Options are validated by the plugin's own zod schema **before** the
|
|
309
|
-
build starts (built-in plugins are strict — an unknown option key is an error); `${ENV_VAR}`
|
|
310
|
-
placeholders inside string options are replaced from the environment (unset → empty string) and
|
|
311
|
-
never printed (archive URLs appear in messages without their query string, so a token passed as
|
|
312
|
-
`?private_token=${TOKEN}` stays out of the logs). A malformed `plugins` entry always fails the
|
|
313
|
-
build (it is the one key the wizard cannot repair). Older c4builder versions ignore the `plugins`
|
|
314
|
-
key, so a rollback keeps building.
|
|
315
|
-
|
|
316
|
-
### `openspec` — publish a local OpenSpec store
|
|
317
|
-
|
|
318
|
-
Renders an [OpenSpec](https://github.com/Fission-AI/OpenSpec) store as a site section:
|
|
319
|
-
a summary (counters, task progress), a page per active change, the specs tree and the archive.
|
|
320
|
-
A change page shows the header (schema, dates, task progress, links to subpages) plus the first
|
|
321
|
-
artifact of `artifacts` (by default `proposal` — the "why" is visible without a click); the
|
|
322
|
-
remaining artifacts (`design`, `tasks`, then any other `*.md` alphabetically) are subpages, and
|
|
323
|
-
spec deltas live under `specs/…` mirroring the folder layout (a folder that has its own
|
|
324
|
-
`spec.md` and nested specs gets one page: the spec followed by the list of nested ones).
|
|
325
|
-
```` ```plantuml ```` / ```` ```d2 ```` fences inside artifacts, deltas and store specs are
|
|
326
|
-
rendered by the **local** engines (nothing is sent to plantuml.com); the image name is derived
|
|
327
|
-
from the fence content, so inserting or reordering fences never reuses a neighbour's cached
|
|
328
|
-
image. A block that fails to render does not fail the build (these blocks used to be rendered by
|
|
329
|
-
the browser, which showed an error image): the page gets a placeholder image and the build prints
|
|
330
|
-
a warning naming the artifact file. Relative links between artifacts of a change point to their pages, referenced files
|
|
331
|
-
(images, notes) are copied next to the page (and to the output root for the complete markdown;
|
|
332
|
-
`excludeOtherFiles` applies). The store folder is watched in `-w`.
|
|
333
|
-
|
|
334
|
-
| Option | Default | Meaning |
|
|
335
|
-
|-------------|--------------------------------|----------------------------------------------------------------|
|
|
336
|
-
| `dir` | `openspec` | store folder (relative to the project directory) |
|
|
337
|
-
| `mount` | `OpenSpec` | section name (and its path in the output folder) |
|
|
338
|
-
| `artifacts` | `["proposal","design","tasks"]`| artifact order; the first one is shown on the change page itself |
|
|
339
|
-
|
|
340
|
-
### `openapi` — swagger-ui pages for a set of OpenAPI specs
|
|
341
|
-
|
|
342
|
-
Finds specs by `glob` in a local folder (`dir`) **or** in a `tar.gz`/`zip` archive fetched over
|
|
343
|
-
HTTP (`archive`, e.g. a GitLab/GitHub repository archive URL; `subdir` picks a folder inside it,
|
|
344
|
-
`headers` adds request headers such as `{"PRIVATE-TOKEN": "${GITLAB_TOKEN}"}` — empty values are
|
|
345
|
-
dropped, so the same config works with and without a token). One page per spec, named after the
|
|
346
|
-
spec's parent folder (file name for specs in the source root), plus an index. All `yaml`/`yml`/
|
|
347
|
-
`json` files of the source are copied into `<mount>/_specs/…` keeping their relative layout, so
|
|
348
|
-
relative `$ref`s (including shared schema files that do not match `glob`) keep resolving; pages
|
|
349
|
-
load swagger-ui from the bundled `vendor/` files — no CDN, no access to the source repository is
|
|
350
|
-
needed by readers. The plugin forces `executeScript` (logged) and injects `swagger-ui.css` and
|
|
351
|
-
`swagger-ui-bundle.js` into `index.html` after the template is rendered (skipped when the template
|
|
352
|
-
already links the bundle), so custom `docsifyTemplate`s need no change. The output folder is never
|
|
353
|
-
treated as a source (`dir: "."` is fine). Archives are downloaded once per process (watch mode
|
|
354
|
-
reuses them). Behind a TLS-intercepting proxy the download fails with `self-signed certificate in
|
|
355
|
-
certificate chain` — point `NODE_EXTRA_CA_CERTS` at the CA bundle (Node reads neither the system
|
|
356
|
-
store nor `SSL_CERT_FILE`); the error message says so as well.
|
|
357
|
-
|
|
358
|
-
| Option | Default | Meaning |
|
|
359
|
-
|-----------|----------------------------------|------------------------------------------|
|
|
360
|
-
| `mount` | `API` | section name |
|
|
361
|
-
| `dir` | — | local folder with specs (watched in `-w`)|
|
|
362
|
-
| `archive` | — | HTTP(S) URL of a tar.gz/zip archive |
|
|
363
|
-
| `subdir` | — | folder inside the archive / `dir` |
|
|
364
|
-
| `headers` | — | HTTP headers for the archive request |
|
|
365
|
-
| `glob` | `**/openapi.{yaml,yml,json}` | spec pattern (`**`, `*`, `?`, `{a,b}`) |
|
|
366
|
-
|
|
367
|
-
Example for a repository that keeps its `openspec/` store next to the C4 sources and consumes
|
|
368
|
-
contracts from another repository:
|
|
369
|
-
|
|
370
|
-
```json
|
|
371
|
-
{
|
|
372
|
-
"plugins": [
|
|
373
|
-
"openspec",
|
|
374
|
-
["openapi", {
|
|
375
|
-
"archive": "https://gitlab.example.com/api/v4/projects/123/repository/archive.tar.gz?sha=main",
|
|
376
|
-
"glob": "*/openapi.yaml",
|
|
377
|
-
"headers": { "PRIVATE-TOKEN": "${GITLAB_TOKEN}" }
|
|
378
|
-
}]
|
|
379
|
-
]
|
|
380
|
-
}
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
### Writing a plugin
|
|
384
|
-
|
|
385
|
-
A plugin is an ESM module whose default export is a plain object (use `definePlugin` from
|
|
386
|
-
`@alfacapital-tech/c4builder/dist/core/plugins/types.js` for typing):
|
|
387
|
-
|
|
388
|
-
```js
|
|
389
|
-
import { z } from 'zod';
|
|
390
|
-
export default {
|
|
391
|
-
name: 'changelog',
|
|
392
|
-
options: z.object({ file: z.string().default('CHANGELOG.md') }).strict(), // optional
|
|
393
|
-
watchPaths: (opts) => [opts.file], // optional
|
|
394
|
-
assets: { styles: ['/abs/path/x.css'], scripts: ['/abs/path/x.js'] }, // optional
|
|
395
|
-
requires: { executeScript: true }, // optional
|
|
396
|
-
async afterScan(ctx, opts) {
|
|
397
|
-
// ctx.tree, ctx.options — the build tree/options; ctx.source({ dir } | { archive, subdir, headers })
|
|
398
|
-
// resolves a folder; ctx.addPage adds a virtual page (missing parents become index pages).
|
|
399
|
-
ctx.addPage({
|
|
400
|
-
path: ['Changelog'],
|
|
401
|
-
markdown: '## Latest\n\n',
|
|
402
|
-
diagrams: [{ file: 'flow.puml', content: '@startuml\nA -> B\n@enduml' }]
|
|
403
|
-
});
|
|
404
|
-
},
|
|
405
|
-
async afterBuild(ctx, opts) { /* ctx.distFolder, ctx.options — copy extra files, run checks */ }
|
|
406
|
-
};
|
|
407
|
-
```
|
|
408
|
-
|
|
409
|
-
Hooks run in the order of the `plugins` list; an exception aborts the build with the plugin's
|
|
410
|
-
name (the previous `dist` backup is kept as usual).
|
|
411
|
-
|
|
412
|
-
# Future plans
|
|
413
|
-
|
|
414
|
-
I would like to bind the **build** phase to the C4 model. It could parse the diagrams and know what Person/System/Component/Container is related to what and help with additional validation. Maybe even export to [structurizr](https://structurizr.com/) or vice versa.
|
|
415
|
-
|
|
416
|
-
The project is still in it's early phase and I intend on using it on some actual projects in order to find more use cases and fix bugs.
|
|
417
|
-
|
|
418
|
-
## Installing a release candidate
|
|
419
|
-
|
|
420
|
-
Pre-release builds (`0.x.y-rc.N`) are published under the npm dist-tag `rc` and never touch
|
|
421
|
-
`latest`:
|
|
422
|
-
|
|
423
|
-
`npm i @alfacapital-tech/c4builder@rc`
|
|
424
|
-
|
|
425
|
-
`npm install` without a tag keeps installing the latest stable version.
|
|
426
|
-
|
|
427
|
-
## Docker
|
|
428
|
-
|
|
429
|
-
The image ships everything needed for a build (Node, JRE, PlantUML jar, fonts, D2) —
|
|
430
|
-
mount a project into `/pwd`:
|
|
61
|
+
Or with Docker (Node, JRE, PlantUML, fonts and D2 included):
|
|
431
62
|
|
|
432
63
|
```bash
|
|
433
64
|
docker run --rm -v "$PWD:/pwd" ghcr.io/alfacapital-tech/c4builder:latest c4builder
|
|
434
65
|
```
|
|
435
66
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
| tag | meaning |
|
|
439
|
-
|---|---|
|
|
440
|
-
| `X.Y.Z`, `sha-…` | immutable releases / commits |
|
|
441
|
-
| `latest` | latest stable release |
|
|
442
|
-
| `rc` | latest release candidate |
|
|
443
|
-
| `edge` | last master commit |
|
|
444
|
-
| `pr-N` | pull request builds |
|
|
445
|
-
|
|
446
|
-
Use the image directly in CI (GitHub Actions, GitLab CI) as the job image — the
|
|
447
|
-
`c4builder` binary is on `PATH`.
|
|
448
|
-
|
|
449
|
-
## Releasing
|
|
450
|
-
|
|
451
|
-
Publishing is triggered by pushing a git tag `v<version>` — pushes/merges to `master` alone
|
|
452
|
-
do not publish.
|
|
67
|
+
Release candidates are published under the `rc` tag: `npm i -g @alfacapital-tech/c4builder@rc`.
|
|
453
68
|
|
|
454
|
-
|
|
455
|
-
the release commit renames it to `## vX.Y.Z`.
|
|
69
|
+
## Documentation
|
|
456
70
|
|
|
457
|
-
|
|
458
|
-
pick each one up automatically):
|
|
71
|
+
The full reference lives on the documentation site, in Russian (primary) and English:
|
|
459
72
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
73
|
+
| | Русский | English |
|
|
74
|
+
|---|---|---|
|
|
75
|
+
| Getting started | [Быстрый старт](https://alfacapital-tech.github.io/C4-Builder/ru/#/01%20Быстрый%20старт/01%20Быстрый%20старт) | [Getting started](https://alfacapital-tech.github.io/C4-Builder/en/#/01%20Getting%20started/01%20Getting%20started) |
|
|
76
|
+
| Diagrams, fonts, `check` | [Диаграммы](https://alfacapital-tech.github.io/C4-Builder/ru/#/03%20Диаграммы/03%20Диаграммы) | [Diagrams](https://alfacapital-tech.github.io/C4-Builder/en/#/03%20Diagrams/03%20Diagrams) |
|
|
77
|
+
| CLI and `.c4builder` keys | [CLI и конфигурация](https://alfacapital-tech.github.io/C4-Builder/ru/#/05%20CLI%20и%20конфигурация/05%20CLI%20и%20конфигурация) | [CLI & configuration](https://alfacapital-tech.github.io/C4-Builder/en/#/05%20CLI%20and%20configuration/05%20CLI%20and%20configuration) |
|
|
78
|
+
| Plugins | [Плагины](https://alfacapital-tech.github.io/C4-Builder/ru/#/06%20Плагины/06%20Плагины) | [Plugins](https://alfacapital-tech.github.io/C4-Builder/en/#/06%20Plugins/06%20Plugins) |
|
|
79
|
+
| Docker and CI | [Docker и CI](https://alfacapital-tech.github.io/C4-Builder/ru/#/07%20Docker%20и%20CI/07%20Docker%20и%20CI) | [Docker & CI](https://alfacapital-tech.github.io/C4-Builder/en/#/07%20Docker%20and%20CI/07%20Docker%20and%20CI) |
|
|
80
|
+
| Working with agents | [Агенты](https://alfacapital-tech.github.io/C4-Builder/ru/#/08%20Агенты/08%20Агенты) | [Agents](https://alfacapital-tech.github.io/C4-Builder/en/#/08%20Agents/08%20Agents) |
|
|
81
|
+
| Development and releases | [Разработка](https://alfacapital-tech.github.io/C4-Builder/ru/#/09%20Разработка/09%20Разработка) | [Development](https://alfacapital-tech.github.io/C4-Builder/en/#/09%20Development/09%20Development) |
|
|
465
82
|
|
|
466
|
-
|
|
83
|
+
What changed in each version: [CHANGELOG.md](https://github.com/AlfaCapital-Tech/C4-Builder/blob/master/CHANGELOG.md).
|
|
84
|
+
Why things are the way they are: the design log (OpenSpec store) on the site.
|
|
467
85
|
|
|
468
|
-
|
|
86
|
+
## Contributing
|
|
469
87
|
|
|
88
|
+
```bash
|
|
89
|
+
npm ci && npm run build
|
|
90
|
+
npm test # all tests, golden rendering snapshots included
|
|
91
|
+
npm run check # biome lint and format
|
|
470
92
|
```
|
|
471
|
-
npm version X.Y.Z -m "release: %s"
|
|
472
|
-
git push --follow-tags
|
|
473
|
-
```
|
|
474
|
-
|
|
475
|
-
Publishes to dist-tag `latest`.
|
|
476
|
-
|
|
477
|
-
# Change log
|
|
478
|
-
|
|
479
|
-
## v0.4.0
|
|
480
|
-
|
|
481
|
-
- Plugin system: `plugins` key in `.c4builder`, `afterScan`/`afterBuild` hooks, virtual pages,
|
|
482
|
-
plugin assets injected into `index.html`, `dir`/`archive` source resolver (see «Plugins»)
|
|
483
|
-
- Built-in plugins: `openspec` (local OpenSpec store → site section, local diagram render) and
|
|
484
|
-
`openapi` (offline swagger-ui pages for a set of OpenAPI specs; `vendor/swagger-ui/swagger-ui.css` 5.32.1)
|
|
485
|
-
- `c4builder check <file...>` — validate individual `.puml` / `.iuml` / `.d2` files with the
|
|
486
|
-
bundled engines, without a project build (#13)
|
|
487
|
-
- D2 compile errors are printed as readable `file:line:col: message` lines instead of raw JSON
|
|
488
|
-
- Regression test for two adjacent `` embeds (#12 — the bug itself was fixed in 0.3.0)
|
|
489
|
-
- Diagram cache key now includes the output path: diagrams that swap contents (or fence blocks
|
|
490
|
-
that shift position) are re-rendered instead of silently reusing a neighbour's cached image.
|
|
491
|
-
The first build after upgrading re-renders everything once.
|
|
492
|
-
- Watch mode ignores the output folder, its backup and `.c4builder*`, and de-duplicates nested
|
|
493
|
-
watch roots (a plugin `dir` covering the project no longer loops the rebuild)
|
|
494
|
-
- A broken ```` ```plantuml ````/```` ```d2 ```` block inside an OpenSpec artifact no longer fails
|
|
495
|
-
the build: the page gets a placeholder image and the warning names the source file
|
|
496
|
-
- Diagram errors name the file the diagram came from (fence names are content hashes)
|
|
497
|
-
- `{a,b}` glob alternatives accept `*`/`?` inside them (`{*.yaml,*.yml}`)
|
|
498
|
-
- Archive download failures caused by a TLS-intercepting proxy suggest `NODE_EXTRA_CA_CERTS`
|
|
499
|
-
- `c4builder site` works as a positional subcommand, the same as `--site` (it is the form the
|
|
500
|
-
post-build hint prints)
|
|
501
|
-
- PlantUML updated to 1.2026.8: filled arrowheads for `>>` decorations in Smetana layout (#14).
|
|
502
|
-
Note: `!pragma layout elk` now requires Java 21
|
|
503
|
-
- Security: runtime dependencies bumped (figlet, tar, qs) to fix npm audit advisories
|
|
504
|
-
|
|
505
|
-
## v0.3.0
|
|
506
|
-
|
|
507
|
-
Full TypeScript rewrite (ESM, Node.js ≥ 20.19) with the same CLI and `.c4builder` format.
|
|
508
|
-
|
|
509
|
-
- PlantUML renders via a direct `java` call with the built-in Smetana layout — graphviz
|
|
510
|
-
is no longer needed; the jar is bundled (`vendor/`)
|
|
511
|
-
- Java itself is optional: system java ≥ 17 is used when present, otherwise a private
|
|
512
|
-
JRE is downloaded automatically (`c4builder jre install` / `jre info`)
|
|
513
|
-
- Second diagram backend: [D2](https://d2lang.com) (`.d2` files, optional
|
|
514
|
-
`@terrastruct/d2` dependency, imports supported)
|
|
515
|
-
- `diagramFormat: png` rasterizes SVG with `@resvg/resvg-js` — deterministic PNG for
|
|
516
|
-
PlantUML and D2 alike
|
|
517
|
-
- Bundled Nimbus Sans font for identical diagram geometry everywhere;
|
|
518
|
-
`useSystemFonts` / `--system-fonts` opts out
|
|
519
|
-
- Config is validated (zod): typos and wrong types fail with a clear message
|
|
520
|
-
- Docker image on GHCR with a tag scheme in sync with npm dist-tags (see [Docker](#docker))
|
|
521
|
-
- PDF output removed — use the docsify site or the single/collection markdown outputs
|
|
522
|
-
instead (the `pdf`/`pdfCss` options no longer exist)
|
|
523
|
-
|
|
524
|
-
## v0.2.20
|
|
525
|
-
|
|
526
|
-
Fork by [Alfa Capital Technologies](https://alfacapital.tech)
|
|
527
|
-
|
|
528
|
-
- Updated commander to v14 (fixed compatibility with Node.js 20+)
|
|
529
|
-
- Updated dependencies: fs-extra 11.x, node-watch 0.7.x
|
|
530
|
-
- PlantUML updated to 1.2025.2
|
|
531
|
-
- Added Dockerfile and CI for building Docker image to GHCR
|
|
532
|
-
- Added CI for npm publishing via OIDC (Trusted Publisher)
|
|
533
|
-
- Published as [@alfacapital-tech/c4builder](https://www.npmjs.com/package/@alfacapital-tech/c4builder)
|
|
534
|
-
|
|
535
|
-
## v0.2.16
|
|
536
|
-
|
|
537
|
-
Partial build (image generation) [#55](https://github.com/adrianvlupu/C4-Builder/pull/58) ([MickeJohannesson](https://github.com/MickeJohannesson))
|
|
538
|
-
|
|
539
|
-
Bugfixes
|
|
540
|
-
|
|
541
|
-
## v0.2.14
|
|
542
|
-
|
|
543
|
-
Diagrams at arbitrary positions [#28](https://github.com/adrianvlupu/C4-Builder/pull/28) ([Sjuanola](https://github.com/sju66))
|
|
544
|
-
|
|
545
|
-
Support for Ditaa Diagrams [#56](https://github.com/adrianvlupu/C4-Builder/pull/56) ([MickeJohannesson](https://github.com/MickeJohannesson))
|
|
546
|
-
|
|
547
|
-
Resolved npm vulnerabilities
|
|
548
|
-
|
|
549
|
-
Latest plantuml jar file 1.2022.3.jar
|
|
550
|
-
|
|
551
|
-
Dockerfile [#51](https://github.com/adrianvlupu/C4-Builder/pull/51) ([craigwardman](https://github.com/craigwardman))
|
|
552
|
-
|
|
553
|
-
Search in site sidebar [#48](https://github.com/adrianvlupu/C4-Builder/pull/48) ([arifinoid](https://github.com/arifinoid))
|
|
554
|
-
|
|
555
|
-
## v0.2.12
|
|
556
|
-
|
|
557
|
-
Relative urls in TOC for multiple markdown files [#9](https://github.com/adrianvlupu/C4-Builder/issues/5).
|
|
558
|
-
|
|
559
|
-
Fixed Processed 1/1..2/2 files bug.
|
|
560
|
-
|
|
561
|
-
Added another version of the PlantUML jar file.
|
|
562
|
-
|
|
563
|
-
## v0.2.11
|
|
564
|
-
|
|
565
|
-
Updated latest plantuml jar to 1.2021.7.jar [#41](https://github.com/adrianvlupu/C4-Builder/pull/41) ([pandasuit](https://github.com/pandasuit))
|
|
566
|
-
|
|
567
|
-
Allow input plantuml source files to use relative include statements to other plantuml files [#42](https://github.com/adrianvlupu/C4-Builder/pull/42) ([pandasuit](https://github.com/pandasuit))
|
|
568
|
-
|
|
569
|
-
Local image generation in sequence due to the jar failing with "dot executable not found".
|
|
570
|
-
|
|
571
|
-
## v0.2.9
|
|
572
|
-
|
|
573
|
-
Updated VSCode snippets and resolved npm audit issues
|
|
574
|
-
|
|
575
|
-
Docsify image plugin [#20](https://github.com/adrianvlupu/C4-Builder/pull/20) ([alefcarlos](https://github.com/alefcarlos))
|
|
576
|
-
|
|
577
|
-
PlantUML 1.2020.17 [#23](https://github.com/adrianvlupu/C4-Builder/pull/23) ([RohanTalip](https://github.com/RohanTalip))
|
|
578
|
-
|
|
579
|
-
Configurable PlantUML Server url [#25](https://github.com/adrianvlupu/C4-Builder/pull/25) ([jikuja](https://github.com/jikuja)), [#29](https://github.com/adrianvlupu/C4-Builder/pull/29) ([coryodaniel](https://github.com/coryodaniel))
|
|
580
|
-
|
|
581
|
-
GitHub Action for running C4 Builder in CI [#16](https://github.com/adrianvlupu/C4-Builder/issues/16) ([hkdobrev](https://github.com/hkdobrev))
|
|
582
|
-
|
|
583
|
-
Overloading the docsify template [#27](https://github.com/adrianvlupu/C4-Builder/pull/27) ([sju66](https://github.com/sju66))
|
|
584
|
-
|
|
585
|
-
## v0.2.12
|
|
586
|
-
|
|
587
|
-
Relative urls in TOC for multiple markdown files [#9](https://github.com/adrianvlupu/C4-Builder/issues/5).
|
|
588
|
-
|
|
589
|
-
Fixed Processed 1/1..2/2 files bug.
|
|
590
|
-
|
|
591
|
-
Added another version of the PlantUML jar file.
|
|
592
|
-
|
|
593
|
-
## v0.2.7
|
|
594
|
-
|
|
595
|
-
Resolved npm audit issues
|
|
596
|
-
|
|
597
|
-
The projects generated now support PlantUML versioning
|
|
598
|
-
|
|
599
|
-
PlantUML jar files included
|
|
600
|
-
|
|
601
|
-
## v0.2.4
|
|
602
|
-
|
|
603
|
-
Solved the limation of including local images in the markdown files.
|
|
604
|
-
|
|
605
|
-
Updated the project template with the diagram descriptions from [C4Model](https://c4model.com/#CoreDiagrams)
|
|
606
|
-
|
|
607
|
-
## v0.2.3
|
|
608
|
-
|
|
609
|
-
Updated template to include the new `Dynamic Diagram` in C4-PlantUML and fixed `npm audit` issues.
|
|
610
|
-
|
|
611
|
-
## v0.2.1 + v0.2.2
|
|
612
|
-
|
|
613
|
-
Added the `c4builder --watch` option and some refactoring.
|
|
614
|
-
|
|
615
|
-
## v0.2.0
|
|
616
|
-
|
|
617
|
-
Pdf generation now uses `puppeteer`. There are no more scaling issues for high resolution displays. Used the `css` file from [vscode-markdown-pdf](https://github.com/yzane/vscode-markdown-pdf.git).
|
|
618
|
-
|
|
619
|
-
Removed unused dependencies.
|
|
620
|
-
|
|
621
|
-
## v0.1.9
|
|
622
|
-
|
|
623
|
-
Thanks to [howiefh](https://github.com/howiefh) for adding the [charset option](https://github.com/adrianvlupu/C4-Builder/pull/1).
|
|
624
|
-
|
|
625
|
-
## v0.1.8
|
|
626
|
-
|
|
627
|
-
Updated template to include the new `Deployment Diagram` in C4-PlantUML and more info inside `readme.md`
|
|
628
|
-
|
|
629
|
-
`node-plantuml` accepted the pull request [#29](https://github.com/markushedvall/node-plantuml/pull/29) so I changed the dependency back to the original repository.
|
|
630
|
-
|
|
631
|
-
## v0.1.7
|
|
632
|
-
|
|
633
|
-
Changed template to include the latest C4-PlantUML`!include https://raw.githubusercontent.com/adrianvlupu/C4-PlantUML/latest/...`
|
|
634
|
-
|
|
635
|
-
## v0.1.6
|
|
636
|
-
|
|
637
|
-
Switched from http-server module to express for serving the static site.
|
|
638
|
-
|
|
639
|
-
Added the option to place diagrams before text.
|
|
640
|
-
|
|
641
|
-
## v0.1.5
|
|
642
|
-
|
|
643
|
-
PlantUML recently switched to V1.2019.6 adding some breaking changes to `!define` and `!definelong`. You can still use them but when calling you have to add `()` method call (http://plantuml.com/preprocessing)
|
|
644
93
|
|
|
645
|
-
|
|
94
|
+
Behaviour changes are described in OpenSpec (`openspec/changes/`) first, add a line to
|
|
95
|
+
`## Unreleased` in `CHANGELOG.md` and update the documentation pages in both languages
|
|
96
|
+
(`docs/ru/src`, `docs/en/src`). Details are on the Development page.
|
|
646
97
|
|
|
647
|
-
|
|
98
|
+
## Credits and license
|
|
648
99
|
|
|
649
|
-
|
|
100
|
+
C4-Builder was created by [Adrian Victor Lupu](https://github.com/adrianvlupu/C4-Builder); this
|
|
101
|
+
fork is maintained by [Alfa Capital Technologies](https://alfacapital.tech). Upstream changes and
|
|
102
|
+
their contributors are listed in the changelog. MIT license, see
|
|
103
|
+
[license](https://github.com/AlfaCapital-Tech/C4-Builder/blob/master/license).
|