@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.
Files changed (39) hide show
  1. package/README.MD +69 -615
  2. package/dist/cli/commands/check.js +43 -26
  3. package/dist/cli/commands/help.js +5 -2
  4. package/dist/cli/commands/jre.js +6 -6
  5. package/dist/cli/commands/list.js +4 -1
  6. package/dist/cli/commands/new.js +6 -6
  7. package/dist/cli/commands/site.js +3 -2
  8. package/dist/cli/dispatch.js +38 -18
  9. package/dist/cli/wizard/collect.js +16 -10
  10. package/dist/config/defaults.js +1 -0
  11. package/dist/config/options.js +1 -1
  12. package/dist/config/schema.js +5 -2
  13. package/dist/core/build.js +15 -6
  14. package/dist/core/compose/docsify.template.js +0 -1
  15. package/dist/core/compose/markdown.js +85 -19
  16. package/dist/core/plugins/hooks.js +1 -1
  17. package/dist/core/plugins/load.js +6 -6
  18. package/dist/core/plugins/source.js +6 -6
  19. package/dist/core/plugins/tree.js +5 -5
  20. package/dist/core/render/bpmnrenderer.js +522 -0
  21. package/dist/core/render/d2renderer.js +19 -19
  22. package/dist/core/render/diagrams.js +64 -45
  23. package/dist/core/render/jre.js +14 -14
  24. package/dist/core/render/pngraster.js +4 -4
  25. package/dist/{plugins/openspec → core/scan}/fences.js +11 -10
  26. package/dist/core/scan/tree.js +37 -14
  27. package/dist/plugins/openapi/index.js +17 -7
  28. package/dist/plugins/openspec/index.js +1 -1
  29. package/dist/plugins/openspec/render.js +5 -2
  30. package/dist/util/archive.js +1 -1
  31. package/dist/util/http.js +3 -3
  32. package/dist/util/lock.js +3 -3
  33. package/dist/util/paths.js +1 -1
  34. package/package.json +9 -4
  35. package/template/AGENTS.md +52 -0
  36. package/template/readme.md +3 -3
  37. package/template/src/5 BPMN Example/account-opening.bpmn +69 -0
  38. package/template/src/5 BPMN Example/account-opening.md +7 -0
  39. package/dist/util/glob.js +0 -69
package/README.MD CHANGED
@@ -1,649 +1,103 @@
1
- # Overview
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
- c4builder is a lightweight nodejs cli tool for building, maintaining and sharing a software architecture project using only text.
3
+ # C4-Builder
4
4
 
5
- The main idea behind the project is that a **developer** could use familiar tools to define software.
5
+ **Architecture as code that an agent writes, checks and reads.**
6
6
 
7
- Combined with **git** any change to the architecture defined in those documents is easily traced. Pull requests, branches, cherry picks and all of the git features could be used as an easier way to keep track of the projects architectural changes.
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
- It relies on these great projects :
13
+ ## Why this fork
10
14
 
11
- - [PlantUml](http://plantuml.com/) creates diagrams from plain text.
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
- - [Markdown](https://guides.github.com/features/mastering-markdown/) creates rich text documents from plant text.
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
- - [C4Model](https://c4model.com/) the idea behind maps of your code
35
+ ## Quick start
16
36
 
17
- - [C4-PlantUML](https://github.com/RicardoNiepel/C4-PlantUML) C4 syntax support for generating plantuml diagrams
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
- <!-- ![idea](docs/images/idea.jpg) -->
26
-
27
- ![edit](docs/images/edit.gif)
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
- ![new](docs/images/new.gif)
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
- $ c4builder --help
68
- Usage: index [options]
40
+ npm i -g @alfacapital-tech/c4builder
69
41
 
70
- Options:
71
- -V, --version output the version number
72
- --new create a new project from template
73
- --name <name> project name for --new (skips the name prompt)
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
- There is also a `jre` subcommand: `c4builder jre install [--force]` pre-downloads the
95
- private JRE cache, `c4builder jre info` prints which Java would be used. `c4builder site`
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
- ### Validating single diagrams
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/c4/context.puml lib/shared.iuml diagrams/flow.d2
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
- `!include` paths resolve relative to the checked file's directory; a `.iuml` library is
111
- validated by including it into an empty diagram.
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
- A minimal pre-commit hook (`.git/hooks/pre-commit`) that validates staged diagrams:
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
- ![wizard](docs/images/build.gif)
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: `![name](<diagram name>.puml)`**
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
- `![name](<diagram name>.d2)`.
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
- ![mds](docs/images/md.gif)
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
- ![basicnav](docs/images/simple-nav.jpg)
241
-
242
- - table of contents (default)
243
-
244
- The table navigation always shows all entities and bolds the current one
245
-
246
- ![tablenav](docs/images/table-nav.jpg)
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
- ![singlemd](docs/images/single-md.jpg)
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
- ![site](docs/images/site.jpg)
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
- ![github](docs/images/githubpages.gif)
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
- ![diagram](https://www.plantuml.com/plantuml/svg/0/fLLDRnen4BqZyH-c72eY4RZqr5CJWff48K5PqgIdQDOxW5j_h6ml9AhwtplsifibJPL3EO0yVfvvy_p6VF41NQYqwlS-I2DKLL3b56n2AFtdoSJXRho...)
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![flow](flow.puml)',
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
- Tags (in sync with npm dist-tags):
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
- Every user-facing PR adds a line to the `## Unreleased` section of the change log below;
455
- the release commit renames it to `## vX.Y.Z`.
69
+ ## Documentation
456
70
 
457
- **Release candidate** (from `master`, as many as needed — consumers pinned to `rc`
458
- pick each one up automatically):
71
+ The full reference lives on the documentation site, in Russian (primary) and English:
459
72
 
460
- ```
461
- npm version X.Y.Z-rc.1 -m "rc: %s" # first candidate
462
- npm version prerelease -m "rc: %s" # next ones: rc.2, rc.3, …
463
- git push --follow-tags
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
- Publishes to npm dist-tag `rc` and docker tag `rc`; `latest` is untouched.
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
- **Final release** (rename `## Unreleased` → `## vX.Y.Z` first):
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 `![..](x.puml)` 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
- Considering they updated their server to use the new version, diagrams generated locally that display correctly won't work on the plantuml server and viceversa
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
- Until the underlying `node-plantuml` package gets updated, I changed the dependency to the fork at https://github.com/adrianvlupu/node-plantuml.git
98
+ ## Credits and license
648
99
 
649
- Also the `!include` directives on each template diagram point to the 1.2019.6 compatible version hosted at https://github.com/adrianvlupu/C4-PlantUML.
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).