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.
Files changed (49) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +3 -3
  3. package/.next/standalone/.next/prerender-manifest.json +3 -3
  4. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  5. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  6. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  7. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  12. package/.next/standalone/.next/server/app/_not-found.rsc +1 -1
  13. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  15. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  16. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  17. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  18. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  19. package/.next/standalone/.next/server/app/index.html +1 -1
  20. package/.next/standalone/.next/server/app/index.rsc +2 -2
  21. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  22. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  23. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  24. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  25. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  26. package/.next/standalone/.next/server/app/page/react-loadable-manifest.json +3 -3
  27. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  28. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  29. package/.next/standalone/.next/server/pages/404.html +1 -1
  30. package/.next/standalone/.next/server/pages/500.html +1 -1
  31. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  32. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  33. package/.next/standalone/.next/static/chunks/002jt~~cq5_aa.js +1 -0
  34. package/.next/standalone/.next/static/chunks/{0.8j.kvn8ne6d.js → 09.y860--~17v.js} +1 -1
  35. package/.next/standalone/.next/static/chunks/0bvf78r89wjl0.js +88 -0
  36. package/.next/standalone/.next/static/chunks/{0~7hzg1mmjrhy.js → 0fv113zapqty~.js} +1 -1
  37. package/.next/standalone/.next/static/chunks/{0eb83nyqnlhcr.js → 0rggo3n729593.js} +1 -1
  38. package/.next/standalone/.next/static/chunks/{0jukf_wt2bw41.js → 0yrtklf4iuj86.js} +2 -2
  39. package/.next/standalone/.next/static/chunks/{0cwgfx0s41pzw.js → 18bi.u.xl8oib.js} +1 -1
  40. package/.next/standalone/.openboard/excalidraw-guide.md +314 -314
  41. package/.next/standalone/.openboard/hooks/pretool-guide.mjs +59 -59
  42. package/.next/standalone/.openboard/hooks/session-hint.mjs +12 -12
  43. package/.next/standalone/package.json +5 -23
  44. package/package.json +4 -23
  45. package/.next/standalone/.next/static/chunks/0r~o4w97q5-v9.js +0 -1
  46. package/.next/standalone/.next/static/chunks/0wh72i_pn1gx6.js +0 -88
  47. /package/.next/standalone/.next/static/{K6al_r4r7ce0W379tfIk2 → 9p_qtnWU8_sxf8umL_DVQ}/_buildManifest.js +0 -0
  48. /package/.next/standalone/.next/static/{K6al_r4r7ce0W379tfIk2 → 9p_qtnWU8_sxf8umL_DVQ}/_clientMiddlewareManifest.js +0 -0
  49. /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.