@zenuml/core 3.46.0 → 3.46.1

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 (55) hide show
  1. package/.claude/skills/dia-scoring/SKILL.md +139 -0
  2. package/.claude/skills/dia-scoring/agents/openai.yaml +7 -0
  3. package/.claude/skills/dia-scoring/references/selectors-and-keys.md +253 -0
  4. package/CLAUDE.md +1 -1
  5. package/bun.lock +25 -11
  6. package/cy/canonical-history.html +908 -0
  7. package/cy/compare-case.html +357 -0
  8. package/cy/compare-cases.js +824 -0
  9. package/cy/compare.html +35 -0
  10. package/cy/diff-algorithm.js +199 -0
  11. package/cy/element-report.html +705 -0
  12. package/cy/icons-test.html +29 -0
  13. package/cy/legacy-vs-html.html +291 -0
  14. package/cy/native-diff-ext/background.js +60 -0
  15. package/cy/native-diff-ext/bridge.js +26 -0
  16. package/cy/native-diff-ext/content.js +194 -0
  17. package/cy/parity-test.html +122 -0
  18. package/cy/return-in-nested-if.html +29 -0
  19. package/cy/svg-preview.html +56 -0
  20. package/cy/svg-test.html +21 -0
  21. package/cy/theme-default-test.html +28 -0
  22. package/dist/stats.html +1 -1
  23. package/dist/zenuml.esm.mjs +16352 -15223
  24. package/dist/zenuml.js +701 -575
  25. package/docs/superpowers/plans/2026-03-23-svg-parity-features.md +283 -0
  26. package/index.html +568 -73
  27. package/package.json +15 -4
  28. package/scripts/analyze-compare-case/collect-data.mjs +991 -0
  29. package/scripts/analyze-compare-case/config.mjs +102 -0
  30. package/scripts/analyze-compare-case/geometry.mjs +101 -0
  31. package/scripts/analyze-compare-case/native-diff.mjs +224 -0
  32. package/scripts/analyze-compare-case/output.mjs +74 -0
  33. package/scripts/analyze-compare-case/panel-diff.mjs +114 -0
  34. package/scripts/analyze-compare-case/report.mjs +157 -0
  35. package/scripts/analyze-compare-case/residual-scopes.mjs +325 -0
  36. package/scripts/analyze-compare-case/scoring.mjs +816 -0
  37. package/scripts/analyze-compare-case.mjs +149 -0
  38. package/scripts/snapshot-dual.js +34 -34
  39. package/skills/dia-scoring/SKILL.md +129 -0
  40. package/skills/dia-scoring/agents/openai.yaml +7 -0
  41. package/skills/dia-scoring/references/selectors-and-keys.md +253 -0
  42. package/test-setup.ts +8 -0
  43. package/types/index.d.ts +56 -0
  44. package/vite.config.ts +4 -0
  45. package/dist/10029-icon-service-Function-Apps-ObflOLuF.js +0 -5
  46. package/dist/Res_AWS-Identity-Access-Management_IAM-Access-Analyzer_48-BPq60XMY.js +0 -11
  47. package/dist/Res_AWS-Lambda_Lambda-Function_48-Co38UB_2.js +0 -12
  48. package/dist/Res_Amazon-EC2_Instance_48-CRaqbNUl.js +0 -12
  49. package/dist/Res_Amazon-Simple-Notification-Service_Topic_48-q13mxUeM.js +0 -11
  50. package/dist/Res_Amazon-Simple-Queue-Service_Queue_48-D2-8gbFw.js +0 -11
  51. package/dist/Robustness_Diagram_Boundary-nYnmTPs8.js +0 -10
  52. package/dist/Robustness_Diagram_Control-DLNLoMxd.js +0 -11
  53. package/dist/Robustness_Diagram_Entity-Be3kcbIE.js +0 -11
  54. package/dist/actor-BMj_HFpo.js +0 -11
  55. package/dist/database-BKHQQWQK.js +0 -8
@@ -0,0 +1,283 @@
1
+ # SVG Parity Features Implementation Plan
2
+
3
+ > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
+
5
+ **Goal:** Add stereotype labels, participant colors, and group rendering to the native SVG renderer to close feature parity gaps before publishing.
6
+
7
+ **Architecture:** Extend the existing data flow: parser model → `OrderedParticipants()` → `IParticipantModel` → `ParticipantGeometry` → SVG rendering. Each feature adds a field to the model interface, passes it through geometry, and renders it in the SVG participant component.
8
+
9
+ **Tech Stack:** TypeScript, SVG, Bun test runner
10
+
11
+ ---
12
+
13
+ ## File Structure
14
+
15
+ | File | Responsibility | Changes |
16
+ |------|---------------|---------|
17
+ | `src/parser/IParticipantModel.ts` | Model interface | Add `stereotype?`, `color?`, `groupId?` |
18
+ | `src/parser/OrderedParticipants.ts` | Parser → model extraction | Pass stereotype, color, groupId from collector |
19
+ | `src/svg/geometry.ts` | Geometry IR types | Add `stereotype?`, `color?`, `groupId?` to `ParticipantGeometry` |
20
+ | `src/svg/buildGeometry.ts` | Geometry builder | Extract new fields in `buildParticipants()` |
21
+ | `src/svg/components/participant.ts` | SVG participant renderer | Render stereotype label, apply color fill |
22
+ | `src/svg/components/group.ts` | **New** — SVG group renderer | Render dashed outline + title bar |
23
+ | `src/svg/composeSvg.ts` | SVG compositor | Render group elements |
24
+ | `cy/compare-cases.js` | Test cases | order-service case already added |
25
+
26
+ ---
27
+
28
+ ### Task 1: Add stereotype to SVG participants
29
+
30
+ **Files:**
31
+ - Modify: `src/parser/IParticipantModel.ts:4-19`
32
+ - Modify: `src/parser/OrderedParticipants.ts:49-59`
33
+ - Modify: `src/svg/geometry.ts:10-24`
34
+ - Modify: `src/svg/buildGeometry.ts:301-312`
35
+ - Modify: `src/svg/components/participant.ts:19-70`
36
+ - Test: `src/svg/renderToSvg.spec.ts`
37
+
38
+ - [ ] **Step 1: Write the failing test**
39
+
40
+ In `src/svg/renderToSvg.spec.ts`, add:
41
+ ```typescript
42
+ it("renders stereotype label on participant", () => {
43
+ const result = renderToSvg('@EC2 <<BFF>> OrderService\nOrderService.method()');
44
+ expect(result.innerSvg).toContain("«BFF»");
45
+ });
46
+ ```
47
+
48
+ - [ ] **Step 2: Run test to verify it fails**
49
+
50
+ Run: `bun run test -- --testPathPattern renderToSvg`
51
+ Expected: FAIL — "«BFF»" not found in output
52
+
53
+ - [ ] **Step 3: Add `stereotype` to `IParticipantModel`**
54
+
55
+ In `src/parser/IParticipantModel.ts`, add `stereotype?: string;` to the interface.
56
+
57
+ - [ ] **Step 4: Pass stereotype from `OrderedParticipants`**
58
+
59
+ In `src/parser/OrderedParticipants.ts:53-58`, pass `participant.stereotype`:
60
+ ```typescript
61
+ return new Participant(
62
+ participant.name,
63
+ previousName,
64
+ participant.label,
65
+ participant.type,
66
+ participant.stereotype, // NEW
67
+ );
68
+ ```
69
+
70
+ Update the `Participant` class constructor (same file, around line 7) to accept and store `stereotype`.
71
+
72
+ - [ ] **Step 5: Add `stereotype` to `ParticipantGeometry`**
73
+
74
+ In `src/svg/geometry.ts`, add to the interface:
75
+ ```typescript
76
+ stereotype?: string;
77
+ ```
78
+
79
+ - [ ] **Step 6: Extract stereotype in `buildParticipants`**
80
+
81
+ In `src/svg/buildGeometry.ts`, in the return object around line 301-312, add:
82
+ ```typescript
83
+ stereotype: m.stereotype,
84
+ ```
85
+
86
+ - [ ] **Step 7: Render stereotype in SVG participant**
87
+
88
+ In `src/svg/components/participant.ts`, in `renderParticipant()`, add stereotype label rendering above the participant name. The stereotype renders as `«text»` in a smaller font, positioned between the icon (if any) and the main label. Reference HTML: `src/components/DiagramFrame/SeqDiagram/LifeLineLayer/Participant.tsx:126-130`.
89
+
90
+ Add after the label text element:
91
+ ```typescript
92
+ if (p.stereotype) {
93
+ const stereoY = textY - 14; // Above main label
94
+ elements.push(`<text x="${textX}" y="${stereoY}" text-anchor="middle" font-size="12" fill="#666">«${escXml(p.stereotype)}»</text>`);
95
+ }
96
+ ```
97
+
98
+ - [ ] **Step 8: Run test to verify it passes**
99
+
100
+ Run: `bun run test -- --testPathPattern renderToSvg`
101
+ Expected: PASS
102
+
103
+ - [ ] **Step 9: Commit**
104
+
105
+ ```bash
106
+ git add -A && git commit -m "feat: add stereotype labels to SVG participants"
107
+ ```
108
+
109
+ ---
110
+
111
+ ### Task 2: Add participant background colors
112
+
113
+ **Files:**
114
+ - Modify: `src/parser/IParticipantModel.ts`
115
+ - Modify: `src/parser/OrderedParticipants.ts`
116
+ - Modify: `src/svg/geometry.ts`
117
+ - Modify: `src/svg/buildGeometry.ts`
118
+ - Modify: `src/svg/components/participant.ts`
119
+ - Test: `src/svg/renderToSvg.spec.ts`
120
+
121
+ - [ ] **Step 1: Write the failing test**
122
+
123
+ ```typescript
124
+ it("renders participant with background color", () => {
125
+ const result = renderToSvg('@Actor Client #FFEBE6\nClient.method()');
126
+ expect(result.innerSvg).toContain('fill="#FFEBE6"');
127
+ });
128
+ ```
129
+
130
+ - [ ] **Step 2: Run test to verify it fails**
131
+
132
+ Run: `bun run test -- --testPathPattern renderToSvg`
133
+ Expected: FAIL
134
+
135
+ - [ ] **Step 3: Add `color` to model, geometry, and builder**
136
+
137
+ Same pattern as Task 1:
138
+ - `IParticipantModel.ts`: add `color?: string`
139
+ - `OrderedParticipants.ts`: pass `participant.color` to constructor
140
+ - `geometry.ts`: add `color?: string` to `ParticipantGeometry`
141
+ - `buildGeometry.ts`: add `color: m.color` to the return object
142
+
143
+ - [ ] **Step 4: Apply color in SVG participant renderer**
144
+
145
+ In `src/svg/components/participant.ts`, modify the participant rect fill:
146
+ ```typescript
147
+ // If color is provided, use it; otherwise use default white
148
+ const fillColor = p.color ? `#${p.color.replace('#', '')}` : "#ffffff";
149
+ ```
150
+
151
+ Apply to the rect element's `fill` attribute. Also compute text color for contrast:
152
+ ```typescript
153
+ // Simple brightness check for text color
154
+ function textColorForBg(hex: string): string {
155
+ const r = parseInt(hex.slice(1, 3), 16);
156
+ const g = parseInt(hex.slice(3, 5), 16);
157
+ const b = parseInt(hex.slice(5, 7), 16);
158
+ return (r * 0.299 + g * 0.587 + b * 0.114) > 186 ? "#333" : "#fff";
159
+ }
160
+ ```
161
+
162
+ - [ ] **Step 5: Run test to verify it passes**
163
+
164
+ Run: `bun run test -- --testPathPattern renderToSvg`
165
+ Expected: PASS
166
+
167
+ - [ ] **Step 6: Commit**
168
+
169
+ ```bash
170
+ git add -A && git commit -m "feat: add participant background colors to SVG renderer"
171
+ ```
172
+
173
+ ---
174
+
175
+ ### Task 3: Add participant group rendering
176
+
177
+ **Files:**
178
+ - Create: `src/svg/components/group.ts`
179
+ - Modify: `src/svg/geometry.ts`
180
+ - Modify: `src/svg/buildGeometry.ts`
181
+ - Modify: `src/svg/composeSvg.ts`
182
+ - Test: `src/svg/renderToSvg.spec.ts`
183
+
184
+ - [ ] **Step 1: Write the failing test**
185
+
186
+ ```typescript
187
+ it("renders participant group container", () => {
188
+ const code = 'group BusinessService {\n @Lambda A\n @Database B\n}\nA.method()';
189
+ const result = renderToSvg(code);
190
+ expect(result.innerSvg).toContain("BusinessService");
191
+ // Group should have a dashed outline
192
+ expect(result.innerSvg).toContain("stroke-dasharray");
193
+ });
194
+ ```
195
+
196
+ - [ ] **Step 2: Run test to verify it fails**
197
+
198
+ Run: `bun run test -- --testPathPattern renderToSvg`
199
+ Expected: FAIL
200
+
201
+ - [ ] **Step 3: Add `GroupGeometry` to geometry types**
202
+
203
+ In `src/svg/geometry.ts`:
204
+ ```typescript
205
+ export interface GroupGeometry {
206
+ name: string;
207
+ x: number;
208
+ y: number;
209
+ width: number;
210
+ height: number;
211
+ }
212
+ ```
213
+
214
+ Add `groups: GroupGeometry[]` to the build result.
215
+
216
+ - [ ] **Step 4: Build group geometry**
217
+
218
+ In `src/svg/buildGeometry.ts`, detect groups from the parser context. The parser's `ToCollector.getParticipants()` returns participants with `groupId`. Group participants that share a `groupId`, compute the bounding box from the leftmost to rightmost participant in the group, and create `GroupGeometry` entries.
219
+
220
+ Key data: Each participant from the collector has `groupId` and the group context has `name().getFormattedText()` for the label.
221
+
222
+ - [ ] **Step 5: Create group SVG renderer**
223
+
224
+ Create `src/svg/components/group.ts`:
225
+ ```typescript
226
+ export function renderGroup(g: GroupGeometry): string {
227
+ // Dashed outline matching HTML's outline-dashed
228
+ return `<g class="participant-group">
229
+ <rect x="${g.x}" y="${g.y}" width="${g.width}" height="${g.height}" fill="none" stroke="#999" stroke-dasharray="4 2" rx="2"/>
230
+ <text x="${g.x + 4}" y="${g.y + 14}" font-size="12" fill="#666">${escXml(g.name)}</text>
231
+ </g>`;
232
+ }
233
+ ```
234
+
235
+ - [ ] **Step 6: Integrate groups into composeSvg**
236
+
237
+ In `src/svg/composeSvg.ts`, render groups before participants (so they appear behind).
238
+
239
+ - [ ] **Step 7: Run test to verify it passes**
240
+
241
+ Run: `bun run test -- --testPathPattern renderToSvg`
242
+ Expected: PASS
243
+
244
+ - [ ] **Step 8: Visual verification**
245
+
246
+ Run: `bun dev` → open `http://localhost:8080/cy/compare-case.html?case=order-service`
247
+ Verify: "BusinessService" group container visible around PurchaseService and InvoiceService
248
+
249
+ - [ ] **Step 9: Commit**
250
+
251
+ ```bash
252
+ git add -A && git commit -m "feat: add participant group rendering to SVG renderer"
253
+ ```
254
+
255
+ ---
256
+
257
+ ### Task 4: Visual verification and regression check
258
+
259
+ - [ ] **Step 1: Run all unit tests**
260
+
261
+ Run: `bun run test`
262
+ Expected: All tests pass
263
+
264
+ - [ ] **Step 2: Check order-service compare case**
265
+
266
+ Open `http://localhost:8080/cy/compare-case.html?case=order-service`
267
+ Verify:
268
+ - Stereotype `«BFF»` appears on OrderService
269
+ - Client has pink (#FFEBE6) background
270
+ - OrderController has blue (#0747A6) background with white text
271
+ - OrderService has green (#E3FCEF) background
272
+ - BusinessService group outline visible around PurchaseService + InvoiceService
273
+
274
+ - [ ] **Step 3: Check existing cases for regressions**
275
+
276
+ Open `http://localhost:8080/cy/compare-case.html?case=self-sync` — should still be ~98%
277
+ Open `http://localhost:8080/cy/compare-case.html?case=demo1-smoke` — check icons + groups
278
+
279
+ - [ ] **Step 4: Final commit if any fixes needed**
280
+
281
+ ```bash
282
+ git add -A && git commit -m "fix: visual parity adjustments"
283
+ ```