obc-cli2 0.2.3 → 0.2.6
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/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +3 -3
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/page/react-loadable-manifest.json +3 -3
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/static/chunks/002jt~~cq5_aa.js +1 -0
- package/.next/standalone/.next/static/chunks/{0.8j.kvn8ne6d.js → 09.y860--~17v.js} +1 -1
- package/.next/standalone/.next/static/chunks/0bvf78r89wjl0.js +88 -0
- package/.next/standalone/.next/static/chunks/{0~7hzg1mmjrhy.js → 0fv113zapqty~.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0eb83nyqnlhcr.js → 0rggo3n729593.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0jukf_wt2bw41.js → 0yrtklf4iuj86.js} +2 -2
- package/.next/standalone/.next/static/chunks/{0cwgfx0s41pzw.js → 18bi.u.xl8oib.js} +1 -1
- package/.next/standalone/.openboard/excalidraw-guide.md +314 -314
- package/.next/standalone/.openboard/hooks/pretool-guide.mjs +59 -59
- package/.next/standalone/.openboard/hooks/session-hint.mjs +12 -12
- package/.next/standalone/package.json +5 -23
- package/package.json +4 -23
- package/.next/standalone/.next/static/chunks/0r~o4w97q5-v9.js +0 -1
- package/.next/standalone/.next/static/chunks/0wh72i_pn1gx6.js +0 -88
- /package/.next/standalone/.next/static/{K6al_r4r7ce0W379tfIk2 → 9p_qtnWU8_sxf8umL_DVQ}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{K6al_r4r7ce0W379tfIk2 → 9p_qtnWU8_sxf8umL_DVQ}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{K6al_r4r7ce0W379tfIk2 → 9p_qtnWU8_sxf8umL_DVQ}/_ssgManifest.js +0 -0
|
@@ -1,314 +1,314 @@
|
|
|
1
|
-
# openboard — Excalidraw JSON Guide for Claude
|
|
2
|
-
|
|
3
|
-
openboard stores the shared whiteboard at `.openboard/board.json`.
|
|
4
|
-
You can read and write this file directly with your file tools.
|
|
5
|
-
The browser polls every 1 second and reflects your changes automatically.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## board.json structure
|
|
10
|
-
|
|
11
|
-
```json
|
|
12
|
-
{
|
|
13
|
-
"elements": [ ...ExcalidrawElement ],
|
|
14
|
-
"files": {}
|
|
15
|
-
}
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
Never include `appState` — `appState.collaborators` is a Map and breaks JSON serialization.
|
|
19
|
-
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
## Design principles
|
|
23
|
-
|
|
24
|
-
**Always produce rich, visually structured diagrams.** A board that uses only rectangles and plain text is a bad board. Apply these principles every time:
|
|
25
|
-
|
|
26
|
-
1. **Use diverse shapes** — choose the shape that best matches the semantic meaning (see shape guide below).
|
|
27
|
-
2. **Express hierarchy clearly** — title size > section label > body text; use indentation, grouping, and color zones.
|
|
28
|
-
3. **Be detailed** — include enough text that the user understands without asking follow-up questions. Prefer more cards over less.
|
|
29
|
-
4. **Use color intentionally** — assign a consistent color per zone/category across the whole board.
|
|
30
|
-
5. **Connect related elements** — use arrows to show flow, dependency, or sequence.
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## Shape semantics — when to use what
|
|
35
|
-
|
|
36
|
-
| Shape | `type` | Best used for |
|
|
37
|
-
| --- | --- | --- |
|
|
38
|
-
| Rectangle | `"rectangle"` | General containers, cards, sections, lists |
|
|
39
|
-
| Diamond | `"diamond"` | Decision points, key choices, branch nodes |
|
|
40
|
-
| Ellipse / Circle | `"ellipse"` | States, actors, start/end nodes, highlights |
|
|
41
|
-
| Arrow | `"arrow"` | Flow, dependency, sequence, causation |
|
|
42
|
-
| Line | `"line"` | Visual dividers, separators, axis |
|
|
43
|
-
| Text (free) | `"text"` | Labels, annotations, titles outside containers |
|
|
44
|
-
|
|
45
|
-
> **Do not use only rectangles.** Vary shapes to make the diagram scannable at a glance.
|
|
46
|
-
|
|
47
|
-
---
|
|
48
|
-
|
|
49
|
-
## Visual hierarchy — font sizes
|
|
50
|
-
|
|
51
|
-
Use these sizes consistently to establish hierarchy:
|
|
52
|
-
|
|
53
|
-
| Level | Role | `fontSize` |
|
|
54
|
-
| --- | --- | --- |
|
|
55
|
-
| H1 | Board title / section heading | `36` |
|
|
56
|
-
| H2 | Sub-section label | `24` |
|
|
57
|
-
| H3 | Card title | `20` |
|
|
58
|
-
| Body | Content inside cards | `16` |
|
|
59
|
-
| Caption | Small annotations | `13` |
|
|
60
|
-
|
|
61
|
-
---
|
|
62
|
-
|
|
63
|
-
## Font families
|
|
64
|
-
|
|
65
|
-
| `fontFamily` | Appearance | Use for |
|
|
66
|
-
| --- | --- | --- |
|
|
67
|
-
| `1` | Virgil — hand-drawn | General diagrams, informal notes |
|
|
68
|
-
| `2` | Helvetica — clean sans-serif | Professional / polished layouts |
|
|
69
|
-
| `3` | Cascadia — monospace | Code, file paths, technical values |
|
|
70
|
-
| `4` | Nunito — rounded | Friendly UI mockups |
|
|
71
|
-
|
|
72
|
-
---
|
|
73
|
-
|
|
74
|
-
## Color palette guide
|
|
75
|
-
|
|
76
|
-
Pick one background color per semantic zone and use it consistently.
|
|
77
|
-
|
|
78
|
-
| Zone | Suggested `backgroundColor` | `strokeColor` |
|
|
79
|
-
| --- | --- | --- |
|
|
80
|
-
| Info / Overview | `"#dbeafe"` (blue-100) | `"#1d4ed8"` |
|
|
81
|
-
| Success / Done | `"#dcfce7"` (green-100) | `"#15803d"` |
|
|
82
|
-
| Warning / In-progress | `"#fef9c3"` (yellow-100) | `"#a16207"` |
|
|
83
|
-
| Danger / Blocked | `"#fee2e2"` (red-100) | `"#b91c1c"` |
|
|
84
|
-
| Neutral / Context | `"#f3f4f6"` (gray-100) | `"#374151"` |
|
|
85
|
-
| Purple / Special | `"#ede9fe"` (violet-100) | `"#6d28d9"` |
|
|
86
|
-
|
|
87
|
-
---
|
|
88
|
-
|
|
89
|
-
## Required fields for every element
|
|
90
|
-
|
|
91
|
-
| field | notes |
|
|
92
|
-
| --- | --- |
|
|
93
|
-
| `type` | `"rectangle"` / `"text"` / `"arrow"` / `"ellipse"` / `"diamond"` / `"line"` |
|
|
94
|
-
| `id` | unique string across all elements |
|
|
95
|
-
| `x`, `y` | position (numbers) |
|
|
96
|
-
| `width`, `height` | size (numbers) |
|
|
97
|
-
| `index` | `"a0"`, `"a1"`, `"a2"` … unique and ascending |
|
|
98
|
-
| `version` | `1` |
|
|
99
|
-
| `versionNonce` | any integer |
|
|
100
|
-
| `updated` | `Date.now()` integer |
|
|
101
|
-
| `isDeleted` | `false` |
|
|
102
|
-
| `fillStyle` | `"solid"` |
|
|
103
|
-
| `strokeWidth` | `2` |
|
|
104
|
-
| `strokeStyle` | `"solid"` |
|
|
105
|
-
| `roughness` | `1` |
|
|
106
|
-
| `opacity` | `100` |
|
|
107
|
-
| `angle` | `0` |
|
|
108
|
-
| `strokeColor` | hex string e.g. `"#1e1e1e"` |
|
|
109
|
-
| `seed` | any integer |
|
|
110
|
-
| `groupIds` | `[]` |
|
|
111
|
-
| `frameId` | `null` |
|
|
112
|
-
| `roundness` | `null` (or `{"type":3}` for rounded corners) |
|
|
113
|
-
| `boundElements` | `[]` |
|
|
114
|
-
| `link` | `null` |
|
|
115
|
-
| `locked` | `false` |
|
|
116
|
-
|
|
117
|
-
---
|
|
118
|
-
|
|
119
|
-
## Element reference
|
|
120
|
-
|
|
121
|
-
### rectangle
|
|
122
|
-
|
|
123
|
-
```json
|
|
124
|
-
{
|
|
125
|
-
"type": "rectangle",
|
|
126
|
-
"backgroundColor": "#dbeafe",
|
|
127
|
-
"strokeColor": "#1d4ed8",
|
|
128
|
-
"roundness": {"type": 3}
|
|
129
|
-
}
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
- Use `roundness: {"type": 3}` for modern rounded cards.
|
|
133
|
-
- `backgroundColor` is the fill; `strokeColor` is the border.
|
|
134
|
-
|
|
135
|
-
### ellipse
|
|
136
|
-
|
|
137
|
-
```json
|
|
138
|
-
{
|
|
139
|
-
"type": "ellipse",
|
|
140
|
-
"width": 120,
|
|
141
|
-
"height": 60,
|
|
142
|
-
"backgroundColor": "#dcfce7",
|
|
143
|
-
"strokeColor": "#15803d"
|
|
144
|
-
}
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
- For a perfect circle, set `width === height`.
|
|
148
|
-
|
|
149
|
-
### diamond
|
|
150
|
-
|
|
151
|
-
```json
|
|
152
|
-
{
|
|
153
|
-
"type": "diamond",
|
|
154
|
-
"width": 160,
|
|
155
|
-
"height": 100,
|
|
156
|
-
"backgroundColor": "#fef9c3",
|
|
157
|
-
"strokeColor": "#a16207"
|
|
158
|
-
}
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
### line (divider)
|
|
162
|
-
|
|
163
|
-
```json
|
|
164
|
-
{
|
|
165
|
-
"type": "line",
|
|
166
|
-
"points": [[0, 0], [400, 0]],
|
|
167
|
-
"strokeColor": "#d1d5db",
|
|
168
|
-
"strokeWidth": 1,
|
|
169
|
-
"startBinding": null,
|
|
170
|
-
"endBinding": null,
|
|
171
|
-
"startArrowhead": null,
|
|
172
|
-
"endArrowhead": null
|
|
173
|
-
}
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
### text (standalone label)
|
|
177
|
-
|
|
178
|
-
```json
|
|
179
|
-
{
|
|
180
|
-
"type": "text",
|
|
181
|
-
"text": "Section Title",
|
|
182
|
-
"originalText": "Section Title",
|
|
183
|
-
"fontSize": 24,
|
|
184
|
-
"fontFamily": 1,
|
|
185
|
-
"textAlign": "left",
|
|
186
|
-
"verticalAlign": "top",
|
|
187
|
-
"containerId": null,
|
|
188
|
-
"autoResize": true,
|
|
189
|
-
"lineHeight": null
|
|
190
|
-
}
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
- **`fontSize` is mandatory** — text is invisible without it.
|
|
194
|
-
- **`backgroundColor` has NO effect on text.** Use a rectangle + `containerId` to show a background color.
|
|
195
|
-
|
|
196
|
-
### text inside a rectangle (card pattern)
|
|
197
|
-
|
|
198
|
-
```json
|
|
199
|
-
[
|
|
200
|
-
{
|
|
201
|
-
"type": "rectangle",
|
|
202
|
-
"id": "card-bg",
|
|
203
|
-
"x": 40, "y": 40, "width": 300, "height": 180,
|
|
204
|
-
"backgroundColor": "#dbeafe",
|
|
205
|
-
"strokeColor": "#1d4ed8",
|
|
206
|
-
"roundness": {"type": 3},
|
|
207
|
-
"boundElements": [{"type": "text", "id": "card-text"}],
|
|
208
|
-
"index": "a0",
|
|
209
|
-
"version": 1, "versionNonce": 1, "updated": 1700000000000,
|
|
210
|
-
"isDeleted": false, "fillStyle": "solid", "strokeWidth": 2,
|
|
211
|
-
"strokeStyle": "solid", "roughness": 1, "opacity": 100,
|
|
212
|
-
"angle": 0, "seed": 1, "groupIds": [], "frameId": null,
|
|
213
|
-
"link": null, "locked": false
|
|
214
|
-
},
|
|
215
|
-
{
|
|
216
|
-
"type": "text",
|
|
217
|
-
"id": "card-text",
|
|
218
|
-
"x": 52, "y": 52, "width": 276, "height": 156,
|
|
219
|
-
"containerId": "card-bg",
|
|
220
|
-
"text": "Card title\n\nBody content here",
|
|
221
|
-
"originalText": "Card title\n\nBody content here",
|
|
222
|
-
"fontSize": 16,
|
|
223
|
-
"fontFamily": 1,
|
|
224
|
-
"textAlign": "left",
|
|
225
|
-
"verticalAlign": "top",
|
|
226
|
-
"autoResize": true,
|
|
227
|
-
"lineHeight": null,
|
|
228
|
-
"index": "a1",
|
|
229
|
-
"version": 1, "versionNonce": 2, "updated": 1700000000000,
|
|
230
|
-
"isDeleted": false, "fillStyle": "solid", "strokeWidth": 2,
|
|
231
|
-
"strokeStyle": "solid", "roughness": 1, "opacity": 100,
|
|
232
|
-
"angle": 0, "strokeColor": "#1e1e1e", "backgroundColor": "transparent",
|
|
233
|
-
"seed": 2, "groupIds": [], "frameId": null, "roundness": null,
|
|
234
|
-
"boundElements": [], "link": null, "locked": false
|
|
235
|
-
}
|
|
236
|
-
]
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
- Text `x`/`y` = rectangle `x`/`y` + 12px inset on each side.
|
|
240
|
-
- Text `width` = rectangle `width` − 24, `height` = rectangle `height` − 24.
|
|
241
|
-
- Rectangle `boundElements` must list the text id.
|
|
242
|
-
|
|
243
|
-
### arrow
|
|
244
|
-
|
|
245
|
-
```json
|
|
246
|
-
{
|
|
247
|
-
"type": "arrow",
|
|
248
|
-
"points": [[0, 0], [160, 0]],
|
|
249
|
-
"startBinding": null,
|
|
250
|
-
"endBinding": null,
|
|
251
|
-
"startArrowhead": null,
|
|
252
|
-
"endArrowhead": "arrow",
|
|
253
|
-
"strokeColor": "#374151",
|
|
254
|
-
"elbowed": false
|
|
255
|
-
}
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
- To attach to shapes, set `startBinding` / `endBinding`:
|
|
259
|
-
|
|
260
|
-
```json
|
|
261
|
-
"startBinding": { "elementId": "shape-a", "focus": 0, "gap": 6 },
|
|
262
|
-
"endBinding": { "elementId": "shape-b", "focus": 0, "gap": 6 }
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
- `endArrowhead`: `"arrow"` (default) / `"triangle"` / `"dot"` / `"bar"` / `null` (no head).
|
|
266
|
-
- `startArrowhead`: same options (use for bidirectional).
|
|
267
|
-
|
|
268
|
-
---
|
|
269
|
-
|
|
270
|
-
## Layout patterns
|
|
271
|
-
|
|
272
|
-
### Hierarchical tree (top → down)
|
|
273
|
-
- Board title as large standalone `text` at top-left (`fontSize: 36`).
|
|
274
|
-
- Section headers as `text` labels (`fontSize: 24`) above each group.
|
|
275
|
-
- Cards (`rectangle` + `text`) arranged in rows with ~20px gap.
|
|
276
|
-
- `arrow` elements pointing downward between levels.
|
|
277
|
-
|
|
278
|
-
### Flow diagram (left → right)
|
|
279
|
-
- `ellipse` for start/end nodes.
|
|
280
|
-
- `rectangle` (rounded) for process steps.
|
|
281
|
-
- `diamond` for decision branches.
|
|
282
|
-
- Horizontal `arrow` elements connecting each step.
|
|
283
|
-
|
|
284
|
-
### Zone-based overview (color blocks)
|
|
285
|
-
- Large background `rectangle` per zone (low opacity or light color) as a backdrop.
|
|
286
|
-
- Cards layered on top within each zone.
|
|
287
|
-
- Zone label as a bold `text` element at the top of each zone.
|
|
288
|
-
- Use different `backgroundColor` per zone (see color palette above).
|
|
289
|
-
|
|
290
|
-
---
|
|
291
|
-
|
|
292
|
-
## Common mistakes
|
|
293
|
-
|
|
294
|
-
| mistake | fix |
|
|
295
|
-
| --- | --- |
|
|
296
|
-
| `backgroundColor` on a `text` element | Use `rectangle` + `containerId` pattern |
|
|
297
|
-
| Missing `fontSize` on text | Add `"fontSize": 16` (minimum) |
|
|
298
|
-
| Missing `index` field | Add unique ascending `"a0"`, `"a1"`, … |
|
|
299
|
-
| Duplicate `id` values | Every element needs a globally unique `id` |
|
|
300
|
-
| Saving `appState` | Never include `appState` in board.json |
|
|
301
|
-
| `files` key missing | Always include `"files": {}` |
|
|
302
|
-
| Only using rectangles | Use diamonds, ellipses, lines, and arrows too |
|
|
303
|
-
| All text the same size | Use H1/H2/H3/Body hierarchy (36/24/20/16) |
|
|
304
|
-
| No color differentiation | Assign one color per zone/category |
|
|
305
|
-
|
|
306
|
-
---
|
|
307
|
-
|
|
308
|
-
## Workflow
|
|
309
|
-
|
|
310
|
-
1. **Read** `.openboard/board.json` to understand the current board state.
|
|
311
|
-
2. **Plan** the layout: identify zones, hierarchy levels, and element types needed.
|
|
312
|
-
3. **Write** the complete updated JSON back to `.openboard/board.json`.
|
|
313
|
-
4. The browser reflects changes within 1 second automatically.
|
|
314
|
-
5. Always read before writing — the user may have made edits in the browser.
|
|
1
|
+
# openboard — Excalidraw JSON Guide for Claude
|
|
2
|
+
|
|
3
|
+
openboard stores the shared whiteboard at `.openboard/board.json`.
|
|
4
|
+
You can read and write this file directly with your file tools.
|
|
5
|
+
The browser polls every 1 second and reflects your changes automatically.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## board.json structure
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"elements": [ ...ExcalidrawElement ],
|
|
14
|
+
"files": {}
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Never include `appState` — `appState.collaborators` is a Map and breaks JSON serialization.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Design principles
|
|
23
|
+
|
|
24
|
+
**Always produce rich, visually structured diagrams.** A board that uses only rectangles and plain text is a bad board. Apply these principles every time:
|
|
25
|
+
|
|
26
|
+
1. **Use diverse shapes** — choose the shape that best matches the semantic meaning (see shape guide below).
|
|
27
|
+
2. **Express hierarchy clearly** — title size > section label > body text; use indentation, grouping, and color zones.
|
|
28
|
+
3. **Be detailed** — include enough text that the user understands without asking follow-up questions. Prefer more cards over less.
|
|
29
|
+
4. **Use color intentionally** — assign a consistent color per zone/category across the whole board.
|
|
30
|
+
5. **Connect related elements** — use arrows to show flow, dependency, or sequence.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Shape semantics — when to use what
|
|
35
|
+
|
|
36
|
+
| Shape | `type` | Best used for |
|
|
37
|
+
| --- | --- | --- |
|
|
38
|
+
| Rectangle | `"rectangle"` | General containers, cards, sections, lists |
|
|
39
|
+
| Diamond | `"diamond"` | Decision points, key choices, branch nodes |
|
|
40
|
+
| Ellipse / Circle | `"ellipse"` | States, actors, start/end nodes, highlights |
|
|
41
|
+
| Arrow | `"arrow"` | Flow, dependency, sequence, causation |
|
|
42
|
+
| Line | `"line"` | Visual dividers, separators, axis |
|
|
43
|
+
| Text (free) | `"text"` | Labels, annotations, titles outside containers |
|
|
44
|
+
|
|
45
|
+
> **Do not use only rectangles.** Vary shapes to make the diagram scannable at a glance.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Visual hierarchy — font sizes
|
|
50
|
+
|
|
51
|
+
Use these sizes consistently to establish hierarchy:
|
|
52
|
+
|
|
53
|
+
| Level | Role | `fontSize` |
|
|
54
|
+
| --- | --- | --- |
|
|
55
|
+
| H1 | Board title / section heading | `36` |
|
|
56
|
+
| H2 | Sub-section label | `24` |
|
|
57
|
+
| H3 | Card title | `20` |
|
|
58
|
+
| Body | Content inside cards | `16` |
|
|
59
|
+
| Caption | Small annotations | `13` |
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Font families
|
|
64
|
+
|
|
65
|
+
| `fontFamily` | Appearance | Use for |
|
|
66
|
+
| --- | --- | --- |
|
|
67
|
+
| `1` | Virgil — hand-drawn | General diagrams, informal notes |
|
|
68
|
+
| `2` | Helvetica — clean sans-serif | Professional / polished layouts |
|
|
69
|
+
| `3` | Cascadia — monospace | Code, file paths, technical values |
|
|
70
|
+
| `4` | Nunito — rounded | Friendly UI mockups |
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Color palette guide
|
|
75
|
+
|
|
76
|
+
Pick one background color per semantic zone and use it consistently.
|
|
77
|
+
|
|
78
|
+
| Zone | Suggested `backgroundColor` | `strokeColor` |
|
|
79
|
+
| --- | --- | --- |
|
|
80
|
+
| Info / Overview | `"#dbeafe"` (blue-100) | `"#1d4ed8"` |
|
|
81
|
+
| Success / Done | `"#dcfce7"` (green-100) | `"#15803d"` |
|
|
82
|
+
| Warning / In-progress | `"#fef9c3"` (yellow-100) | `"#a16207"` |
|
|
83
|
+
| Danger / Blocked | `"#fee2e2"` (red-100) | `"#b91c1c"` |
|
|
84
|
+
| Neutral / Context | `"#f3f4f6"` (gray-100) | `"#374151"` |
|
|
85
|
+
| Purple / Special | `"#ede9fe"` (violet-100) | `"#6d28d9"` |
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Required fields for every element
|
|
90
|
+
|
|
91
|
+
| field | notes |
|
|
92
|
+
| --- | --- |
|
|
93
|
+
| `type` | `"rectangle"` / `"text"` / `"arrow"` / `"ellipse"` / `"diamond"` / `"line"` |
|
|
94
|
+
| `id` | unique string across all elements |
|
|
95
|
+
| `x`, `y` | position (numbers) |
|
|
96
|
+
| `width`, `height` | size (numbers) |
|
|
97
|
+
| `index` | `"a0"`, `"a1"`, `"a2"` … unique and ascending |
|
|
98
|
+
| `version` | `1` |
|
|
99
|
+
| `versionNonce` | any integer |
|
|
100
|
+
| `updated` | `Date.now()` integer |
|
|
101
|
+
| `isDeleted` | `false` |
|
|
102
|
+
| `fillStyle` | `"solid"` |
|
|
103
|
+
| `strokeWidth` | `2` |
|
|
104
|
+
| `strokeStyle` | `"solid"` |
|
|
105
|
+
| `roughness` | `1` |
|
|
106
|
+
| `opacity` | `100` |
|
|
107
|
+
| `angle` | `0` |
|
|
108
|
+
| `strokeColor` | hex string e.g. `"#1e1e1e"` |
|
|
109
|
+
| `seed` | any integer |
|
|
110
|
+
| `groupIds` | `[]` |
|
|
111
|
+
| `frameId` | `null` |
|
|
112
|
+
| `roundness` | `null` (or `{"type":3}` for rounded corners) |
|
|
113
|
+
| `boundElements` | `[]` |
|
|
114
|
+
| `link` | `null` |
|
|
115
|
+
| `locked` | `false` |
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Element reference
|
|
120
|
+
|
|
121
|
+
### rectangle
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"type": "rectangle",
|
|
126
|
+
"backgroundColor": "#dbeafe",
|
|
127
|
+
"strokeColor": "#1d4ed8",
|
|
128
|
+
"roundness": {"type": 3}
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
- Use `roundness: {"type": 3}` for modern rounded cards.
|
|
133
|
+
- `backgroundColor` is the fill; `strokeColor` is the border.
|
|
134
|
+
|
|
135
|
+
### ellipse
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"type": "ellipse",
|
|
140
|
+
"width": 120,
|
|
141
|
+
"height": 60,
|
|
142
|
+
"backgroundColor": "#dcfce7",
|
|
143
|
+
"strokeColor": "#15803d"
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
- For a perfect circle, set `width === height`.
|
|
148
|
+
|
|
149
|
+
### diamond
|
|
150
|
+
|
|
151
|
+
```json
|
|
152
|
+
{
|
|
153
|
+
"type": "diamond",
|
|
154
|
+
"width": 160,
|
|
155
|
+
"height": 100,
|
|
156
|
+
"backgroundColor": "#fef9c3",
|
|
157
|
+
"strokeColor": "#a16207"
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### line (divider)
|
|
162
|
+
|
|
163
|
+
```json
|
|
164
|
+
{
|
|
165
|
+
"type": "line",
|
|
166
|
+
"points": [[0, 0], [400, 0]],
|
|
167
|
+
"strokeColor": "#d1d5db",
|
|
168
|
+
"strokeWidth": 1,
|
|
169
|
+
"startBinding": null,
|
|
170
|
+
"endBinding": null,
|
|
171
|
+
"startArrowhead": null,
|
|
172
|
+
"endArrowhead": null
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### text (standalone label)
|
|
177
|
+
|
|
178
|
+
```json
|
|
179
|
+
{
|
|
180
|
+
"type": "text",
|
|
181
|
+
"text": "Section Title",
|
|
182
|
+
"originalText": "Section Title",
|
|
183
|
+
"fontSize": 24,
|
|
184
|
+
"fontFamily": 1,
|
|
185
|
+
"textAlign": "left",
|
|
186
|
+
"verticalAlign": "top",
|
|
187
|
+
"containerId": null,
|
|
188
|
+
"autoResize": true,
|
|
189
|
+
"lineHeight": null
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
- **`fontSize` is mandatory** — text is invisible without it.
|
|
194
|
+
- **`backgroundColor` has NO effect on text.** Use a rectangle + `containerId` to show a background color.
|
|
195
|
+
|
|
196
|
+
### text inside a rectangle (card pattern)
|
|
197
|
+
|
|
198
|
+
```json
|
|
199
|
+
[
|
|
200
|
+
{
|
|
201
|
+
"type": "rectangle",
|
|
202
|
+
"id": "card-bg",
|
|
203
|
+
"x": 40, "y": 40, "width": 300, "height": 180,
|
|
204
|
+
"backgroundColor": "#dbeafe",
|
|
205
|
+
"strokeColor": "#1d4ed8",
|
|
206
|
+
"roundness": {"type": 3},
|
|
207
|
+
"boundElements": [{"type": "text", "id": "card-text"}],
|
|
208
|
+
"index": "a0",
|
|
209
|
+
"version": 1, "versionNonce": 1, "updated": 1700000000000,
|
|
210
|
+
"isDeleted": false, "fillStyle": "solid", "strokeWidth": 2,
|
|
211
|
+
"strokeStyle": "solid", "roughness": 1, "opacity": 100,
|
|
212
|
+
"angle": 0, "seed": 1, "groupIds": [], "frameId": null,
|
|
213
|
+
"link": null, "locked": false
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
"type": "text",
|
|
217
|
+
"id": "card-text",
|
|
218
|
+
"x": 52, "y": 52, "width": 276, "height": 156,
|
|
219
|
+
"containerId": "card-bg",
|
|
220
|
+
"text": "Card title\n\nBody content here",
|
|
221
|
+
"originalText": "Card title\n\nBody content here",
|
|
222
|
+
"fontSize": 16,
|
|
223
|
+
"fontFamily": 1,
|
|
224
|
+
"textAlign": "left",
|
|
225
|
+
"verticalAlign": "top",
|
|
226
|
+
"autoResize": true,
|
|
227
|
+
"lineHeight": null,
|
|
228
|
+
"index": "a1",
|
|
229
|
+
"version": 1, "versionNonce": 2, "updated": 1700000000000,
|
|
230
|
+
"isDeleted": false, "fillStyle": "solid", "strokeWidth": 2,
|
|
231
|
+
"strokeStyle": "solid", "roughness": 1, "opacity": 100,
|
|
232
|
+
"angle": 0, "strokeColor": "#1e1e1e", "backgroundColor": "transparent",
|
|
233
|
+
"seed": 2, "groupIds": [], "frameId": null, "roundness": null,
|
|
234
|
+
"boundElements": [], "link": null, "locked": false
|
|
235
|
+
}
|
|
236
|
+
]
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
- Text `x`/`y` = rectangle `x`/`y` + 12px inset on each side.
|
|
240
|
+
- Text `width` = rectangle `width` − 24, `height` = rectangle `height` − 24.
|
|
241
|
+
- Rectangle `boundElements` must list the text id.
|
|
242
|
+
|
|
243
|
+
### arrow
|
|
244
|
+
|
|
245
|
+
```json
|
|
246
|
+
{
|
|
247
|
+
"type": "arrow",
|
|
248
|
+
"points": [[0, 0], [160, 0]],
|
|
249
|
+
"startBinding": null,
|
|
250
|
+
"endBinding": null,
|
|
251
|
+
"startArrowhead": null,
|
|
252
|
+
"endArrowhead": "arrow",
|
|
253
|
+
"strokeColor": "#374151",
|
|
254
|
+
"elbowed": false
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
- To attach to shapes, set `startBinding` / `endBinding`:
|
|
259
|
+
|
|
260
|
+
```json
|
|
261
|
+
"startBinding": { "elementId": "shape-a", "focus": 0, "gap": 6 },
|
|
262
|
+
"endBinding": { "elementId": "shape-b", "focus": 0, "gap": 6 }
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
- `endArrowhead`: `"arrow"` (default) / `"triangle"` / `"dot"` / `"bar"` / `null` (no head).
|
|
266
|
+
- `startArrowhead`: same options (use for bidirectional).
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## Layout patterns
|
|
271
|
+
|
|
272
|
+
### Hierarchical tree (top → down)
|
|
273
|
+
- Board title as large standalone `text` at top-left (`fontSize: 36`).
|
|
274
|
+
- Section headers as `text` labels (`fontSize: 24`) above each group.
|
|
275
|
+
- Cards (`rectangle` + `text`) arranged in rows with ~20px gap.
|
|
276
|
+
- `arrow` elements pointing downward between levels.
|
|
277
|
+
|
|
278
|
+
### Flow diagram (left → right)
|
|
279
|
+
- `ellipse` for start/end nodes.
|
|
280
|
+
- `rectangle` (rounded) for process steps.
|
|
281
|
+
- `diamond` for decision branches.
|
|
282
|
+
- Horizontal `arrow` elements connecting each step.
|
|
283
|
+
|
|
284
|
+
### Zone-based overview (color blocks)
|
|
285
|
+
- Large background `rectangle` per zone (low opacity or light color) as a backdrop.
|
|
286
|
+
- Cards layered on top within each zone.
|
|
287
|
+
- Zone label as a bold `text` element at the top of each zone.
|
|
288
|
+
- Use different `backgroundColor` per zone (see color palette above).
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## Common mistakes
|
|
293
|
+
|
|
294
|
+
| mistake | fix |
|
|
295
|
+
| --- | --- |
|
|
296
|
+
| `backgroundColor` on a `text` element | Use `rectangle` + `containerId` pattern |
|
|
297
|
+
| Missing `fontSize` on text | Add `"fontSize": 16` (minimum) |
|
|
298
|
+
| Missing `index` field | Add unique ascending `"a0"`, `"a1"`, … |
|
|
299
|
+
| Duplicate `id` values | Every element needs a globally unique `id` |
|
|
300
|
+
| Saving `appState` | Never include `appState` in board.json |
|
|
301
|
+
| `files` key missing | Always include `"files": {}` |
|
|
302
|
+
| Only using rectangles | Use diamonds, ellipses, lines, and arrows too |
|
|
303
|
+
| All text the same size | Use H1/H2/H3/Body hierarchy (36/24/20/16) |
|
|
304
|
+
| No color differentiation | Assign one color per zone/category |
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
## Workflow
|
|
309
|
+
|
|
310
|
+
1. **Read** `.openboard/board.json` to understand the current board state.
|
|
311
|
+
2. **Plan** the layout: identify zones, hierarchy levels, and element types needed.
|
|
312
|
+
3. **Write** the complete updated JSON back to `.openboard/board.json`.
|
|
313
|
+
4. The browser reflects changes within 1 second automatically.
|
|
314
|
+
5. Always read before writing — the user may have made edits in the browser.
|