@alfacapital-tech/c4builder 0.9.0 → 0.10.0-rc.2
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 +3 -2
- package/dist/cli/commands/new.js +3 -0
- package/dist/cli/commands/site.js +11 -4
- package/dist/cli/commands/skills.js +80 -0
- package/dist/cli/dispatch.js +55 -6
- package/dist/cli/update.js +1 -1
- package/dist/core/build.js +3 -7
- package/dist/index.js +9 -1
- package/dist/util/utils.js +9 -3
- package/package.json +2 -1
- package/skills/c4builder/SKILL.md +199 -0
- package/skills/c4builder/references/bpmn.md +138 -0
- package/skills/c4builder/references/config.md +111 -0
- package/skills/c4builder/references/diagrams.md +77 -0
- package/skills/c4builder/references/mermaid.md +78 -0
- package/skills/c4builder/references/plugins.md +68 -0
- package/skills/c4builder-review/SKILL.md +97 -0
- package/skills/c4builder-setup/SKILL.md +130 -0
- package/template/AGENTS.md +13 -2
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# BPMN reference
|
|
2
|
+
|
|
3
|
+
`.bpmn` files are business processes in BPMN 2.0 notation. Write **only the semantic model**;
|
|
4
|
+
c4builder validates it, lays it out (horizontal pools and lanes, flow left to right) and
|
|
5
|
+
renders it in the standard bpmn.io notation — offline and deterministically.
|
|
6
|
+
|
|
7
|
+
## Source format
|
|
8
|
+
|
|
9
|
+
- Standard BPMN 2.0 XML, namespace `http://www.omg.org/spec/BPMN/20100524/MODEL`.
|
|
10
|
+
- **No coordinates.** Do not write a `bpmndi:BPMNDiagram` section: it is ignored anyway, the
|
|
11
|
+
build always computes the layout. There is no way to hand-tune positions.
|
|
12
|
+
- `incoming` / `outgoing` elements are optional — connections are taken from
|
|
13
|
+
`sourceRef` / `targetRef` of the flows.
|
|
14
|
+
- `isExecutable="false"`: this is documentation, not an executable process; no Camunda or
|
|
15
|
+
Flowable extensions are needed.
|
|
16
|
+
- Give elements readable ids with a type prefix (`Task_CheckDocuments`, `Gateway_Decision`,
|
|
17
|
+
`Flow_Approved`): every error message points to an id.
|
|
18
|
+
|
|
19
|
+
Minimal example — a pool with two lanes, an external "black-box" pool, a gateway with
|
|
20
|
+
labelled branches, a boundary timer and message flows:
|
|
21
|
+
|
|
22
|
+
```xml
|
|
23
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
24
|
+
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"
|
|
25
|
+
id="Definitions_Order" targetNamespace="https://example.com/bpmn/order">
|
|
26
|
+
<bpmn:collaboration id="Collaboration_Order">
|
|
27
|
+
<bpmn:participant id="Pool_Shop" name="Shop" processRef="Process_Order" />
|
|
28
|
+
<bpmn:participant id="Pool_Bank" name="Payment bank" />
|
|
29
|
+
<bpmn:messageFlow id="Message_Charge" name="Charge request"
|
|
30
|
+
sourceRef="Task_Charge" targetRef="Pool_Bank" />
|
|
31
|
+
<bpmn:messageFlow id="Message_Result" name="Payment result"
|
|
32
|
+
sourceRef="Pool_Bank" targetRef="Task_AwaitPayment" />
|
|
33
|
+
</bpmn:collaboration>
|
|
34
|
+
<bpmn:process id="Process_Order" name="Order" isExecutable="false">
|
|
35
|
+
<bpmn:laneSet id="LaneSet_Shop">
|
|
36
|
+
<bpmn:lane id="Lane_Sales" name="Sales">
|
|
37
|
+
<bpmn:flowNodeRef>Start_Order</bpmn:flowNodeRef>
|
|
38
|
+
<bpmn:flowNodeRef>Task_Charge</bpmn:flowNodeRef>
|
|
39
|
+
<bpmn:flowNodeRef>Task_AwaitPayment</bpmn:flowNodeRef>
|
|
40
|
+
<bpmn:flowNodeRef>Gateway_Paid</bpmn:flowNodeRef>
|
|
41
|
+
<bpmn:flowNodeRef>End_Cancelled</bpmn:flowNodeRef>
|
|
42
|
+
<bpmn:flowNodeRef>End_Expired</bpmn:flowNodeRef>
|
|
43
|
+
</bpmn:lane>
|
|
44
|
+
<bpmn:lane id="Lane_Warehouse" name="Warehouse">
|
|
45
|
+
<bpmn:flowNodeRef>Task_Ship</bpmn:flowNodeRef>
|
|
46
|
+
<bpmn:flowNodeRef>End_Shipped</bpmn:flowNodeRef>
|
|
47
|
+
</bpmn:lane>
|
|
48
|
+
</bpmn:laneSet>
|
|
49
|
+
<bpmn:startEvent id="Start_Order" name="Order placed" />
|
|
50
|
+
<bpmn:sendTask id="Task_Charge" name="Request payment" />
|
|
51
|
+
<bpmn:receiveTask id="Task_AwaitPayment" name="Await payment" />
|
|
52
|
+
<bpmn:boundaryEvent id="Timer_PaymentTimeout" name="1 hour" attachedToRef="Task_AwaitPayment">
|
|
53
|
+
<bpmn:timerEventDefinition id="TimerDef_PaymentTimeout" />
|
|
54
|
+
</bpmn:boundaryEvent>
|
|
55
|
+
<bpmn:exclusiveGateway id="Gateway_Paid" name="Paid?" />
|
|
56
|
+
<bpmn:userTask id="Task_Ship" name="Ship order" />
|
|
57
|
+
<bpmn:endEvent id="End_Shipped" name="Order shipped" />
|
|
58
|
+
<bpmn:endEvent id="End_Cancelled" name="Order cancelled" />
|
|
59
|
+
<bpmn:endEvent id="End_Expired" name="Payment expired" />
|
|
60
|
+
<bpmn:sequenceFlow id="Flow_Start" sourceRef="Start_Order" targetRef="Task_Charge" />
|
|
61
|
+
<bpmn:sequenceFlow id="Flow_Charged" sourceRef="Task_Charge" targetRef="Task_AwaitPayment" />
|
|
62
|
+
<bpmn:sequenceFlow id="Flow_Answered" sourceRef="Task_AwaitPayment" targetRef="Gateway_Paid" />
|
|
63
|
+
<bpmn:sequenceFlow id="Flow_Yes" name="Yes" sourceRef="Gateway_Paid" targetRef="Task_Ship" />
|
|
64
|
+
<bpmn:sequenceFlow id="Flow_No" name="No" sourceRef="Gateway_Paid" targetRef="End_Cancelled" />
|
|
65
|
+
<bpmn:sequenceFlow id="Flow_Timeout" sourceRef="Timer_PaymentTimeout" targetRef="End_Expired" />
|
|
66
|
+
<bpmn:sequenceFlow id="Flow_Shipped" sourceRef="Task_Ship" targetRef="End_Shipped" />
|
|
67
|
+
</bpmn:process>
|
|
68
|
+
</bpmn:definitions>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Elements that render: start/end/intermediate events with timer, message, error and other
|
|
72
|
+
definitions, boundary events, `task`, `userTask`, `serviceTask`, `sendTask`, `receiveTask`,
|
|
73
|
+
`manualTask`, `scriptTask`, `businessRuleTask`, exclusive/parallel/inclusive/event-based
|
|
74
|
+
gateways, `subProcess`, `textAnnotation` with `association`, `dataObjectReference`.
|
|
75
|
+
`complexGateway` is not supported by the layout engine.
|
|
76
|
+
|
|
77
|
+
## Modelling conventions
|
|
78
|
+
|
|
79
|
+
- **Pool = organization**, **lane = role or unit inside it.** An external party whose
|
|
80
|
+
internals you do not describe is a pool without `processRef` (a black box).
|
|
81
|
+
- **Between pools — only message flows.** Sequence flows stay inside one pool; a message
|
|
82
|
+
flow may target a node or the black-box pool itself.
|
|
83
|
+
- **Lanes:** when a process has lanes, list every flow node in exactly one lane
|
|
84
|
+
(`flowNodeRef`). Boundary events may be left out — they sit on their task.
|
|
85
|
+
- **Label everything:** events, tasks, participants, lanes and diverging gateways need a
|
|
86
|
+
`name`. Label every outgoing flow of an exclusive/inclusive gateway (`Yes` / `No`).
|
|
87
|
+
- **Exactly the start and end you mean:** a process needs a start and an end event; a node
|
|
88
|
+
without incoming or outgoing flows is an error, not an implicit start or end.
|
|
89
|
+
- **Overview plus detail** instead of one huge diagram: above ~40 nodes the picture stops
|
|
90
|
+
being readable. Sub-processes are always drawn collapsed — describe their inside in a
|
|
91
|
+
separate `.bpmn` on its own page.
|
|
92
|
+
|
|
93
|
+
## The loop
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
c4builder check "src/3 Processes/order.bpmn"
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
`check` runs the whole pipeline — parse, rules, layout and rendering — without a project.
|
|
100
|
+
Exit code 0 means the diagram builds; warnings are printed but do not change the code. Each
|
|
101
|
+
problem is one line:
|
|
102
|
+
|
|
103
|
+
```text
|
|
104
|
+
✗ src/3 Processes/order.bpmn: Task_Ship [no-disconnected] Element is not connected
|
|
105
|
+
⚠ src/3 Processes/order.bpmn: Flow_No [c4builder/gateway-flow-labels] Outgoing flow of a diverging gateway has no label
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Format: `<file>: <element id> [<rule>] <description>`. Fix the element with that id and run
|
|
109
|
+
`check` again until the exit code is 0.
|
|
110
|
+
|
|
111
|
+
| Message | Fix |
|
|
112
|
+
|---|---|
|
|
113
|
+
| `[no-disconnected]`, `[no-implicit-start]`, `[no-implicit-end]` | connect the node with sequence flows (check `sourceRef`/`targetRef` spelling) |
|
|
114
|
+
| `[start-event-required]`, `[end-event-required]` | add the missing start or end event |
|
|
115
|
+
| `[label-required]` | add a `name` |
|
|
116
|
+
| `[c4builder/lane-membership]` | list the node in exactly one `flowNodeRef` of its process lanes |
|
|
117
|
+
| `[c4builder/sequence-flow-in-pool]` | replace the sequence flow between pools with a `messageFlow` in the collaboration |
|
|
118
|
+
| `[c4builder/message-flow-between-pools]` | a message flow inside one pool must be a sequence flow |
|
|
119
|
+
| `[c4builder/gateway-flow-labels]` (warning) | name the gateway's outgoing flows |
|
|
120
|
+
| `[no-inclusive-gateway]` (warning) | prefer exclusive or parallel gateways where possible |
|
|
121
|
+
| `X: unresolved reference <Y>` | element `X` refers to an id `Y` that does not exist |
|
|
122
|
+
| `invalid BPMN XML: …` | the file is not well-formed XML or not BPMN 2.0 |
|
|
123
|
+
| `layout failed: …` / `layout lost N element(s): …` | the layout engine could not place the model: simplify it, split it into overview and detail, or move the listed elements |
|
|
124
|
+
|
|
125
|
+
The rule set is fixed (bpmnlint `recommended` without `no-bpmndi`, plus the `c4builder/*`
|
|
126
|
+
rules) and is the same in `check` and in the build — there is no project config for it.
|
|
127
|
+
|
|
128
|
+
## Output and dependencies
|
|
129
|
+
|
|
130
|
+
- The image is `<name>.svg` (or `.png` with `diagramFormat: png`) next to the page; place
|
|
131
|
+
it inline with ``. In `llms-full.txt` the source appears in an `xml`
|
|
132
|
+
block.
|
|
133
|
+
- Text is measured with the bundled Nimbus Sans: the SVG is identical on every machine;
|
|
134
|
+
`useSystemFonts` does not affect BPMN.
|
|
135
|
+
- The engine packages (`bpmn-js`, `bpmn-moddle`, `bpmnlint`, `bpmn-auto-layout`, `jsdom`)
|
|
136
|
+
are optional npm dependencies, loaded only when the project has a `.bpmn`. An install with
|
|
137
|
+
`--omit=optional` stops such a build with a hint to reinstall c4builder.
|
|
138
|
+
- Like D2, BPMN has no online renderer: `generateLocalImages` must stay `true`.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# `.c4builder` reference
|
|
2
|
+
|
|
3
|
+
`.c4builder` is a JSON file in the project root (another path: `c4builder -c <path>`).
|
|
4
|
+
`c4builder --list` prints the effective values, `c4builder --docs` explains the wizard
|
|
5
|
+
questions, `c4builder --config` re-runs the wizard (interactive — prefer editing the JSON).
|
|
6
|
+
|
|
7
|
+
Validation rules:
|
|
8
|
+
|
|
9
|
+
- **Unknown keys are silently dropped.** A misspelled key (`generateWeb`) changes nothing —
|
|
10
|
+
compare every key with the tables below.
|
|
11
|
+
- A wrong type (a string where a boolean is expected, a bad port) fails the build with a
|
|
12
|
+
message naming the key. `null` means "not set" → default.
|
|
13
|
+
- The wizard asks for every key it knows that is **missing** from the file, so a
|
|
14
|
+
non-interactive build needs a complete config — like the one
|
|
15
|
+
`c4builder --new --name <name> -y` writes (below). `hasRun: true` (set after the first
|
|
16
|
+
successful build) makes invalid values fail the build instead of being asked again.
|
|
17
|
+
|
|
18
|
+
## Sources and outputs
|
|
19
|
+
|
|
20
|
+
| Key | Default | Meaning |
|
|
21
|
+
|---|---|---|
|
|
22
|
+
| `projectName` | — | documentation title; name of the complete markdown file |
|
|
23
|
+
| `homepageName` | `Overview` | title of the root page |
|
|
24
|
+
| `rootFolder` | `src` | source folder |
|
|
25
|
+
| `distFolder` | `docs` | output folder — **wiped on every build** |
|
|
26
|
+
| `generateMD` | `true` | markdown collection: `README.md` per folder |
|
|
27
|
+
| `generateCompleteMD` | `false` | one `<projectName>.md` with everything |
|
|
28
|
+
| `generateWEB` | `true` | docsify site (`index.html`, `<folder>.md` per folder) |
|
|
29
|
+
| `generateLLMS` | `true` in new projects, off when absent | `llms.txt` (page index) and `llms-full.txt` (full text, diagrams as source) in the site root; needs `generateWEB` |
|
|
30
|
+
| `excludeOtherFiles` | `false` | do not copy non-diagram, non-markdown files (images…) |
|
|
31
|
+
|
|
32
|
+
## Page content
|
|
33
|
+
|
|
34
|
+
| Key | Default | Meaning |
|
|
35
|
+
|---|---|---|
|
|
36
|
+
| `diagramsOnTop` | `true` | attached diagrams before the text (after a leading `#` title) |
|
|
37
|
+
| `includeBreadcrumbs` | `true` | folder path under the title |
|
|
38
|
+
| `includeNavigation` | `false` | markdown collection: links to parent and children |
|
|
39
|
+
| `includeTableOfContents` | `true` | markdown collection: tree of all pages on every page |
|
|
40
|
+
| `includeLinkToDiagram` | `false` | a link to the image instead of the image |
|
|
41
|
+
| `embedDiagram` | `false` | images inlined as base64 data URIs |
|
|
42
|
+
| `charset` | `UTF-8` | encoding of diagram sources |
|
|
43
|
+
|
|
44
|
+
## Diagrams
|
|
45
|
+
|
|
46
|
+
| Key | Default | Meaning |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| `generateLocalImages` | `true` | render locally (Java + bundled PlantUML, bundled D2). `false` = PlantUML images are links to `plantumlServerUrl`; a project with `.d2` files then fails |
|
|
49
|
+
| `plantumlServerUrl` | `https://www.plantuml.com/plantuml` | server for `generateLocalImages: false` |
|
|
50
|
+
| `diagramFormat` | `svg` | `svg` or `png` (PNG is rasterized from SVG; ditaa is always PNG) |
|
|
51
|
+
| `d2Layout` | `dagre` | D2 layout engine: `dagre` or `elk` |
|
|
52
|
+
| `useSystemFonts` | `false` | machine fonts instead of the bundled one — output differs per machine (`--system-fonts` for one run) |
|
|
53
|
+
|
|
54
|
+
## Site (docsify)
|
|
55
|
+
|
|
56
|
+
| Key | Default | Meaning |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| `webPort` | `3000` | port of `c4builder --site` (`-p <n>` overrides) |
|
|
59
|
+
| `questionsHeading` | `Open questions` | heading of the section in the source `.md` where `site -w` appends questions left on the page |
|
|
60
|
+
| `uiLanguage` | `auto` | language of the `site -w` page interface: `auto` (browser language), `en` or `ru`; CLI output and feedback batches stay English |
|
|
61
|
+
| `webTheme` | `vendor/vue.css` | docsify theme stylesheet |
|
|
62
|
+
| `supportSearch` | `true` | search box in the sidebar |
|
|
63
|
+
| `repoUrl` | `""` | repository link in the site corner |
|
|
64
|
+
| `executeScript` | `false` | let docsify run `<script>` in pages (forced on by `openapi`) |
|
|
65
|
+
| `docsifyTemplate` | `""` | path to a JS module exporting a function that returns `index.html` |
|
|
66
|
+
| `webFileName` | — | fixed file name for every site page instead of the folder name |
|
|
67
|
+
| `excludeSidebarFolderByPath` | — | array of folder paths, **including** `rootFolder` (`"src/2 Deployment"`), hidden from the sidebar |
|
|
68
|
+
|
|
69
|
+
## Plugins
|
|
70
|
+
|
|
71
|
+
| Key | Default | Meaning |
|
|
72
|
+
|---|---|---|
|
|
73
|
+
| `plugins` | `[]` | `"name"` or `["name", { options }]` — see [plugins.md](plugins.md). Unlike other keys, a malformed entry always fails the build |
|
|
74
|
+
|
|
75
|
+
Legacy keys (`plantumlVersion`, `generatePDF`, `generateCompletePDF`) only produce a
|
|
76
|
+
warning — remove them when you see one.
|
|
77
|
+
|
|
78
|
+
Complete config written by `c4builder --new --name demo -y` — start from it when adding
|
|
79
|
+
c4builder to an existing repository:
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"projectName": "demo",
|
|
84
|
+
"homepageName": "Overview",
|
|
85
|
+
"rootFolder": "src",
|
|
86
|
+
"distFolder": "docs",
|
|
87
|
+
"generateMD": true,
|
|
88
|
+
"generateCompleteMD": false,
|
|
89
|
+
"generateWEB": true,
|
|
90
|
+
"generateLLMS": true,
|
|
91
|
+
"includeNavigation": false,
|
|
92
|
+
"includeTableOfContents": true,
|
|
93
|
+
"webTheme": "vendor/vue.css",
|
|
94
|
+
"supportSearch": true,
|
|
95
|
+
"repoUrl": "",
|
|
96
|
+
"executeScript": false,
|
|
97
|
+
"docsifyTemplate": "",
|
|
98
|
+
"webPort": "3000",
|
|
99
|
+
"includeBreadcrumbs": true,
|
|
100
|
+
"includeLinkToDiagram": false,
|
|
101
|
+
"diagramsOnTop": true,
|
|
102
|
+
"embedDiagram": false,
|
|
103
|
+
"excludeOtherFiles": false,
|
|
104
|
+
"generateLocalImages": true,
|
|
105
|
+
"plantumlServerUrl": "https://www.plantuml.com/plantuml",
|
|
106
|
+
"diagramFormat": "svg",
|
|
107
|
+
"d2Layout": "dagre",
|
|
108
|
+
"charset": "UTF-8",
|
|
109
|
+
"useSystemFonts": false
|
|
110
|
+
}
|
|
111
|
+
```
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Diagrams reference
|
|
2
|
+
|
|
3
|
+
The backend is chosen by file extension: `.puml` → PlantUML, `.d2` → D2, `.bpmn` → BPMN
|
|
4
|
+
(validation + automatic layout + bpmn-js, see [bpmn.md](bpmn.md)), `.mmd` → mermaid (see
|
|
5
|
+
[mermaid.md](mermaid.md)). All of them can live in one project and one folder (with different
|
|
6
|
+
base names).
|
|
7
|
+
|
|
8
|
+
## PlantUML and C4-PlantUML
|
|
9
|
+
|
|
10
|
+
Rendering is offline: the PlantUML jar is bundled and runs on Java 17+ with the built-in
|
|
11
|
+
Smetana layout — Graphviz is not used. `!pragma layout elk` needs Java 21.
|
|
12
|
+
|
|
13
|
+
**C4 includes** come from the PlantUML stdlib (C4-PlantUML is inside the jar):
|
|
14
|
+
|
|
15
|
+
| Level | Include | Main macros |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| System context | `!include <C4/C4_Context>` | `Person`, `System`, `System_Ext`, `Rel` |
|
|
18
|
+
| Container | `!include <C4/C4_Container>` | `Container`, `ContainerDb`, `ContainerQueue`, `System_Boundary` |
|
|
19
|
+
| Component | `!include <C4/C4_Component>` | `Component`, `ComponentDb`, `Container_Boundary` |
|
|
20
|
+
| Dynamic | `!include <C4/C4_Dynamic>` | numbered `Rel` steps |
|
|
21
|
+
| Deployment | `!include <C4/C4_Deployment>` | `Deployment_Node`, `Node` |
|
|
22
|
+
|
|
23
|
+
Each level includes the previous ones. `LAYOUT_WITH_LEGEND()`, `LAYOUT_TOP_DOWN()`,
|
|
24
|
+
`LAYOUT_LEFT_RIGHT()` control layout and legend. Do not include C4 by URL
|
|
25
|
+
(`!include https://…`, `!includeurl`): it needs network on every build and pins nothing.
|
|
26
|
+
|
|
27
|
+
**Shared styles** — one `.iuml` library included after the C4 include, by a path relative
|
|
28
|
+
to the including diagram:
|
|
29
|
+
|
|
30
|
+
```plantuml
|
|
31
|
+
@startuml
|
|
32
|
+
!include <C4/C4_Context>
|
|
33
|
+
!include ../styles.iuml
|
|
34
|
+
...
|
|
35
|
+
@enduml
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Put `skinparam`s and `UpdateElementStyle(...)` / `AddElementTag(...)` calls there. A `.iuml`
|
|
39
|
+
is never rendered on its own; it is copied to the output like any other file (prefix it
|
|
40
|
+
with `_` to keep it out). Editing an included file re-renders every diagram that includes
|
|
41
|
+
it.
|
|
42
|
+
|
|
43
|
+
**Other PlantUML diagrams** (sequence, class, activity, state, ditaa…) work the same way —
|
|
44
|
+
any `@startuml` file is rendered. ditaa (`@startditaa`) always produces PNG.
|
|
45
|
+
|
|
46
|
+
**Non-Latin text.** Sources are read as UTF-8 (`charset`). The bundled Nimbus Sans font
|
|
47
|
+
covers Latin, Cyrillic and Greek, so diagrams look identical on every machine. Scripts it
|
|
48
|
+
lacks (e.g. CJK) need `useSystemFonts: true` (or `c4builder --system-fonts` for one run)
|
|
49
|
+
and a system font that has them — the output then depends on the machine.
|
|
50
|
+
|
|
51
|
+
## D2
|
|
52
|
+
|
|
53
|
+
`.d2` files are rendered by the bundled D2 engine (WASM → SVG), which is the optional npm
|
|
54
|
+
dependency `@terrastruct/d2`. A `.d2` file in a project without it stops the build with an
|
|
55
|
+
install hint. D2 has no online renderer, so `generateLocalImages` must stay `true`.
|
|
56
|
+
|
|
57
|
+
- Imports: `@file` / spread `...@file` (without the `.d2` extension), resolved by
|
|
58
|
+
c4builder itself — no network. Keep shared classes in a `_`-prefixed file
|
|
59
|
+
(`src/_c4lib.d2`) and import it with `...@../_c4lib` from a nested folder.
|
|
60
|
+
- Layout: `d2Layout` — `dagre` (default) or `elk`.
|
|
61
|
+
- Validate like PlantUML: `c4builder check path/to/diagram.d2`.
|
|
62
|
+
|
|
63
|
+
## Placement and output
|
|
64
|
+
|
|
65
|
+
- Every diagram of a folder is attached to the folder's page; `` /
|
|
66
|
+
`` / `` / `` in a markdown file of the same folder places it
|
|
67
|
+
inline instead.
|
|
68
|
+
- Image file = diagram base name + `.svg` (or `.png` with `diagramFormat: png`), next to
|
|
69
|
+
the page in the output.
|
|
70
|
+
- A ```` ```plantuml ```` block in a page `.md` is rendered at build time like a `.puml`
|
|
71
|
+
file and replaced by its image in every output (`@startuml` optional, `!include` relative
|
|
72
|
+
to the page folder, a broken block becomes a placeholder plus a warning). To show diagram
|
|
73
|
+
source as code, fence it as `puml` or `text` — those, like `d2` blocks, stay code. A
|
|
74
|
+
```` ```mermaid ```` block is rendered the same way ([mermaid.md](mermaid.md)).
|
|
75
|
+
- `embedDiagram: true` inlines images as base64; `includeLinkToDiagram: true` replaces
|
|
76
|
+
images with links.
|
|
77
|
+
- Unchanged diagrams are reused from the previous build (checksums in `.c4builder.cache`).
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Mermaid reference
|
|
2
|
+
|
|
3
|
+
Mermaid diagrams are rendered **at build time** by real mermaid (the official
|
|
4
|
+
`@mermaid-js/tiny` build) running in jsdom — no browser, no network. Text is measured with
|
|
5
|
+
the bundled Nimbus Sans, so the SVG is identical on every machine. Every output (site,
|
|
6
|
+
markdown, complete markdown, PNG) gets an image; the browser never sees diagram source.
|
|
7
|
+
|
|
8
|
+
## When mermaid, when PlantUML
|
|
9
|
+
|
|
10
|
+
- **C4 model** (context, containers, components, deployment) — PlantUML with the C4 stdlib,
|
|
11
|
+
see [diagrams.md](diagrams.md). Mermaid C4 diagrams may lay out differently than in a browser.
|
|
12
|
+
- **Mermaid** — flows and processes inside documentation and OpenSpec artifacts:
|
|
13
|
+
`flowchart`/`graph` (with `subgraph`), `sequenceDiagram`, `stateDiagram-v2`, `erDiagram`,
|
|
14
|
+
`classDiagram`, `gantt`, `pie` and other types of the tiny build.
|
|
15
|
+
- **Business processes with pools and lanes** — BPMN, see [bpmn.md](bpmn.md).
|
|
16
|
+
|
|
17
|
+
## Two sources
|
|
18
|
+
|
|
19
|
+
- **A `.mmd` file** in a page folder, like `.puml`/`.d2`/`.bpmn`: rendered to `<name>.svg`
|
|
20
|
+
(or `.png` with `diagramFormat: png`) and attached to the page, or placed inline with
|
|
21
|
+
``. `flow.mmd` and `flow.puml` in one folder collide on the image name.
|
|
22
|
+
- **A ```` ```mermaid ```` block** in a page `.md` or in an OpenSpec artifact (`design.md`,
|
|
23
|
+
`proposal.md`, specs): replaced by its image in every output, like a ```` ```plantuml ````
|
|
24
|
+
block. To show mermaid source as code instead, fence it as `text`.
|
|
25
|
+
|
|
26
|
+
```mermaid
|
|
27
|
+
sequenceDiagram
|
|
28
|
+
participant К as Клиент
|
|
29
|
+
participant Б as Банк
|
|
30
|
+
К->>Б: Заявка на счёт
|
|
31
|
+
Note right of Б: проверка анкеты
|
|
32
|
+
Б-->>К: Счёт открыт
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Conventions
|
|
36
|
+
|
|
37
|
+
- Keep labels short. A label longer than ~200 px wraps at spaces; a single long word
|
|
38
|
+
without spaces is split by mermaid character by character.
|
|
39
|
+
- Non-Latin text (Cyrillic etc.) works in ids and labels.
|
|
40
|
+
- The look is fixed: `look: classic`, theme `default`, SVG text labels. `%%{init: …}%%` and
|
|
41
|
+
frontmatter `config:` cannot change `look`, `htmlLabels`, `fontFamily`, `securityLevel` or
|
|
42
|
+
`themeCSS`; other keys (`theme`, `flowchart.curve`, spacing) work as in mermaid.
|
|
43
|
+
- Not supported: `mindmap`, `architecture` and KaTeX math (`$$…$$`) — they are not in the
|
|
44
|
+
tiny build and fail with an explicit `unsupported mermaid …` error.
|
|
45
|
+
- Clicks, tooltips and links are not interactive: the image is static.
|
|
46
|
+
|
|
47
|
+
## The loop
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
c4builder check "src/3 Processes/flow.mmd"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`check` parses and renders the file exactly like the build, without a project. Exit code 0
|
|
54
|
+
means the diagram builds. Errors carry the line of the file (frontmatter and comments
|
|
55
|
+
counted):
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
✗ src/3 Processes/flow.mmd: line 3: ...A --> B B -->> ((C; Expecting 'AMP', 'COLON', 'PIPE', ..., got 'TAGEND'
|
|
59
|
+
✗ src/3 Processes/map.mmd: line 1: unsupported mermaid diagram type 'mindmap'
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Fix the line and run `check` again until the exit code is 0, then build. A
|
|
63
|
+
```` ```mermaid ```` block cannot be checked on its own: build the project and read the
|
|
64
|
+
warnings, or copy the block into a temporary `.mmd`.
|
|
65
|
+
|
|
66
|
+
- An error in a `.mmd` file fails the build with the file path and line.
|
|
67
|
+
- An error in a ```` ```mermaid ```` block does not: the build exits with 0, the image is
|
|
68
|
+
a placeholder with the error, and the log has a warning naming the source `.md`.
|
|
69
|
+
|
|
70
|
+
## Output and dependencies
|
|
71
|
+
|
|
72
|
+
- In `llms-full.txt` a mermaid diagram (file or block) appears as its source in a
|
|
73
|
+
`mermaid` block.
|
|
74
|
+
- The engine package `@mermaid-js/tiny` (about 2.7 MB, with `jsdom`) is an optional npm
|
|
75
|
+
dependency, loaded only when the project has mermaid. An install with `--omit=optional`
|
|
76
|
+
stops a `.mmd` build (and turns blocks into placeholders) with a hint to reinstall c4builder
|
|
77
|
+
without that flag.
|
|
78
|
+
- Like D2 and BPMN, mermaid has no online renderer: `generateLocalImages` must stay `true`.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Plugins reference
|
|
2
|
+
|
|
3
|
+
Plugins add pages from outside `rootFolder` (they go through the normal pipeline: sidebar,
|
|
4
|
+
search, markdown outputs, local diagram rendering) and site assets. They are listed in
|
|
5
|
+
`.c4builder`:
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"plugins": [
|
|
10
|
+
"openspec",
|
|
11
|
+
["openapi", { "dir": "../contracts", "glob": "*/openapi.yaml" }]
|
|
12
|
+
]
|
|
13
|
+
}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
- An entry is `"name"` or `["name", { options }]`. A malformed entry always fails the build.
|
|
17
|
+
- Name resolution: built-in (`openspec`, `openapi`) → local ESM module
|
|
18
|
+
(`./plugins/my.mjs`, relative to the project) → npm package installed in the project.
|
|
19
|
+
- Options are validated before the build; built-in plugins reject unknown option keys.
|
|
20
|
+
- `${ENV_VAR}` inside string options is replaced from the environment (unset → empty) and
|
|
21
|
+
never printed — keep tokens there, not in the file.
|
|
22
|
+
- Plugin folders are watched by `c4builder --site -w`.
|
|
23
|
+
- Hooks run in list order; an exception aborts the build and names the plugin.
|
|
24
|
+
|
|
25
|
+
## `openspec` — OpenSpec store as a site section
|
|
26
|
+
|
|
27
|
+
Renders an [OpenSpec](https://github.com/Fission-AI/OpenSpec) store: a summary page
|
|
28
|
+
(counters, task progress), one page per active change (header + first artifact, the other
|
|
29
|
+
artifacts and spec deltas as subpages), the specs tree and the archive. `plantuml` / `d2`
|
|
30
|
+
fenced blocks in artifacts are rendered by the local engines; a broken block gets a
|
|
31
|
+
placeholder image and a warning naming the file instead of failing the build.
|
|
32
|
+
|
|
33
|
+
| Option | Default | Meaning |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| `dir` | `openspec` | store folder, relative to the project |
|
|
36
|
+
| `mount` | `OpenSpec` | section name and its path in the output |
|
|
37
|
+
| `artifacts` | `["proposal", "design", "tasks"]` | artifact order; the first is shown on the change page |
|
|
38
|
+
| `parentKey` | — | `.openspec.yaml` key pointing at the parent change (e.g. `x-parent`); when set, child changes are nested under their parent in the sidebar, the Changes table and the archive |
|
|
39
|
+
| `groupKey` | — | `.openspec.yaml` key with the change's group (e.g. `x-team`); when set, top-level changes go to `Changes/<group>/<id>`, the Changes table and the archive get per-group sections |
|
|
40
|
+
| `nameKey` | — | `.openspec.yaml` key with the change's name (e.g. `x-name`); when set, the name labels the top-level change and is its page path segment (falls back to the id on `/`, `#`, `?` or a duplicate) |
|
|
41
|
+
| `columns` | — | extra Changes table columns from `.openspec.yaml`: `[{ "key": "x-assignee", "title": "Assignee" }]`; missing value — `—` |
|
|
42
|
+
|
|
43
|
+
## `openapi` — swagger-ui pages for OpenAPI specs
|
|
44
|
+
|
|
45
|
+
One page per spec found by `glob` (named after the spec's parent folder) plus an index;
|
|
46
|
+
swagger-ui is bundled, readers need no network. Exactly one source — `dir` **or**
|
|
47
|
+
`archive` — is required. It forces `executeScript: true`.
|
|
48
|
+
|
|
49
|
+
| Option | Default | Meaning |
|
|
50
|
+
|---|---|---|
|
|
51
|
+
| `mount` | `API` | section name |
|
|
52
|
+
| `dir` | — | local folder with specs (watched) |
|
|
53
|
+
| `archive` | — | HTTP(S) URL of a `tar.gz` / `zip` archive (e.g. a repository archive) |
|
|
54
|
+
| `subdir` | — | folder inside the archive or `dir` |
|
|
55
|
+
| `headers` | — | HTTP headers for the archive request, e.g. `{"PRIVATE-TOKEN": "${GITLAB_TOKEN}"}` |
|
|
56
|
+
| `glob` | `**/openapi.{yaml,yml,json}` | spec pattern (`**`, `*`, `?`, `{a,b}`); directories starting with a dot are skipped |
|
|
57
|
+
|
|
58
|
+
All `yaml`/`yml`/`json` files of the source are published under `<mount>/_specs/…` with
|
|
59
|
+
their relative layout, so relative `$ref`s keep working. Archive download fails with
|
|
60
|
+
`self-signed certificate in certificate chain` behind a TLS-intercepting proxy → set
|
|
61
|
+
`NODE_EXTRA_CA_CERTS` to the proxy CA bundle.
|
|
62
|
+
|
|
63
|
+
## Custom plugins
|
|
64
|
+
|
|
65
|
+
A plugin is an ESM module whose default export is an object with `name` and optional
|
|
66
|
+
`options` (zod schema), `watchPaths`, `assets`, `requires`, `afterScan(ctx, opts)` (add
|
|
67
|
+
virtual pages with `ctx.addPage`) and `afterBuild(ctx, opts)`. See the "Writing a plugin"
|
|
68
|
+
section of the c4builder README for the full contract and an example.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: c4builder-review
|
|
3
|
+
description: Review c4builder pages with a human right on the local site - the human selects text in c4builder --site -w and leaves comments with the Feedback button, the agent receives them in batches with c4builder feedback --wait --as <name>, edits the sources and waits for the next batch until Approve. Use when asked to discuss a change on the site, to show the pages or a design, to review a page, the design or OpenSpec artifacts, when the human says they will leave comments on the page, right after proposing an OpenSpec change in a repository with c4builder, and on /c4builder-review [change-id|page].
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# c4builder-review: page comments to the agent
|
|
7
|
+
|
|
8
|
+
The human looks at the pages in the browser (`c4builder --site -w`), selects text and presses:
|
|
9
|
+
|
|
10
|
+
- **Feedback** — a comment to you. It is not written to the files and comes to you in a batch:
|
|
11
|
+
**Send now** sends one comment, **Add to review** → **Submit review** sends several (from several
|
|
12
|
+
pages too), **Approve** means nothing more to change.
|
|
13
|
+
- **Question** — a question for people: c4builder appends it to the source `.md` under the
|
|
14
|
+
`questionsHeading` section (`Open questions` by default). It is not a task for you — leave it
|
|
15
|
+
alone unless asked.
|
|
16
|
+
|
|
17
|
+
Invocation: `/c4builder-review [change-id|page]`. The port is `webPort` from `.c4builder`
|
|
18
|
+
(`<port>` below); when the server runs with `-p <n>`, pass the same `-p <n>` to the commands below.
|
|
19
|
+
|
|
20
|
+
The listener name (`<name>` below) is how the page picks the agent when several share one
|
|
21
|
+
`site -w`: the change id from the argument, otherwise the name of your task. Letters, digits,
|
|
22
|
+
`.`, `_`, `-`, up to 64 characters. Keep one name for the whole review.
|
|
23
|
+
|
|
24
|
+
## 1. Server
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:<port>/
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`200` — the server is up; never start a second one. Otherwise ask the user to start
|
|
31
|
+
`c4builder --site -w`, or ask whether you may start it yourself in the background — many teams
|
|
32
|
+
keep the preview server in the human's hands.
|
|
33
|
+
|
|
34
|
+
## 2. Link
|
|
35
|
+
|
|
36
|
+
- Argument is an OpenSpec change id: find its page in the build output (`distFolder` from
|
|
37
|
+
`.c4builder`, `docs` by default). The path depends on the `mount`, `groupKey` and `nameKey`
|
|
38
|
+
options of the `openspec` plugin — search, do not guess:
|
|
39
|
+
`find <distFolder> -path '*<change-id>*' -name '*.md' | head` (with `nameKey` the folder carries
|
|
40
|
+
the change's name from its `.openspec.yaml` instead of the id). The address is
|
|
41
|
+
`http://localhost:<port>/#/<path without .md>`.
|
|
42
|
+
- Argument is a page or a section: find it in the build output the same way.
|
|
43
|
+
- No argument: the home page `http://localhost:<port>/`.
|
|
44
|
+
|
|
45
|
+
Give the link, remind in two lines what **Feedback** and **Question** do (see above) and say your
|
|
46
|
+
listener name: with several agents the human picks it in **Send to** on the review bar.
|
|
47
|
+
|
|
48
|
+
## 3. Wait
|
|
49
|
+
|
|
50
|
+
Start in the background (in Claude Code: Bash with `run_in_background`):
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
c4builder feedback --wait --as <name>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
It exits when a batch arrives; its stdout is the batch. Connecting turns the **Feedback** button
|
|
57
|
+
on by itself, the server needs no restart. Errors:
|
|
58
|
+
|
|
59
|
+
- `--as <name> is required` (exit code 2) — the name is missing or invalid: fix it and run again;
|
|
60
|
+
- `no c4builder site -w on …` (exit code 1) — no server or it crashed: back to step 1;
|
|
61
|
+
- `agent feedback is disabled on …` (exit code 1) — the server runs without `-w` or with
|
|
62
|
+
`--no-agent`: ask the user to restart `c4builder --site -w`;
|
|
63
|
+
- `unknown command: feedback` or `unknown option '--as'` — the CLI is older than this skill: tell
|
|
64
|
+
the user, `c4builder update` updates it (only when they agree).
|
|
65
|
+
|
|
66
|
+
## 4. Batch
|
|
67
|
+
|
|
68
|
+
```text
|
|
69
|
+
# Page feedback (c4builder)
|
|
70
|
+
|
|
71
|
+
Decision: submitted
|
|
72
|
+
Comments: 1 on 1 page
|
|
73
|
+
|
|
74
|
+
## 1. OpenSpec/Changes/add-dark-mode/design.md (§ D3)
|
|
75
|
+
Sources: openspec/changes/add-dark-mode/design.md
|
|
76
|
+
Quote: "the selected text"
|
|
77
|
+
|
|
78
|
+
> what to change
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Every comment names the site page, the page section (`§`), its source files (`Sources`) and the
|
|
82
|
+
quoted selection; `## General` is the overall comment of a review.
|
|
83
|
+
|
|
84
|
+
- Edit the files listed in `Sources` (change artifacts, `src/` and so on), never the build output.
|
|
85
|
+
No `Sources` — find the quote in the sources (`grep -rn`). The page reloads by itself.
|
|
86
|
+
- Do not copy comments into the questions section: they are instructions to you, not questions
|
|
87
|
+
for people.
|
|
88
|
+
- A comment that is unclear or debatable — ask in the chat instead of guessing; do the rest of the
|
|
89
|
+
batch.
|
|
90
|
+
- After the edits report briefly in the chat what you did for each comment number. Then run
|
|
91
|
+
`c4builder feedback --wait --as <name>` in the background again with the same name — batches
|
|
92
|
+
wait in your mailbox.
|
|
93
|
+
|
|
94
|
+
## 5. Done
|
|
95
|
+
|
|
96
|
+
`Decision: approved` — nothing more to change: apply the comments of that batch, if any, give a
|
|
97
|
+
summary of the changes by file and stop waiting. Do not commit unless the user asks.
|