sad-mcp 2.3.5 → 2.3.7
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/dist/bpmn/layout.d.ts +1 -1
- package/dist/bpmn/layout.js +10 -17
- package/dist/bpmn/svg.js +19 -5
- package/package.json +1 -1
- package/skills/uml-class-diagram/SKILL.md +1 -0
- package/skills/uml-state-diagram/NOTATION.md +1 -1
- package/skills/uml-state-diagram/SKILL.md +2 -0
- package/skills/uml-use-case-diagram/SKILL.md +3 -0
package/dist/bpmn/layout.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export declare const L: {
|
|
|
12
12
|
readonly POOL_VGAP: 16;
|
|
13
13
|
readonly LANE_MIN_H: 140;
|
|
14
14
|
readonly LANE_CORRIDOR_H: 56;
|
|
15
|
-
readonly EMPTY_POOL_H:
|
|
15
|
+
readonly EMPTY_POOL_H: 96;
|
|
16
16
|
readonly CANVAS_TOP: 72;
|
|
17
17
|
readonly CANVAS_LEFT_PAD: 20;
|
|
18
18
|
readonly CANVAS_RIGHT_PAD: 40;
|
package/dist/bpmn/layout.js
CHANGED
|
@@ -31,7 +31,7 @@ export const L = {
|
|
|
31
31
|
POOL_VGAP: 16,
|
|
32
32
|
LANE_MIN_H: 140,
|
|
33
33
|
LANE_CORRIDOR_H: 56, // bottom band for data stores/objects
|
|
34
|
-
EMPTY_POOL_H:
|
|
34
|
+
EMPTY_POOL_H: 96, // tall enough for a wrapped 2-line pool label
|
|
35
35
|
CANVAS_TOP: 72, // room for header bar above diagram
|
|
36
36
|
CANVAS_LEFT_PAD: 20,
|
|
37
37
|
CANVAS_RIGHT_PAD: 40,
|
|
@@ -389,10 +389,10 @@ export function layoutModel(m) {
|
|
|
389
389
|
// ── Pool ordering ──────────────────────────────────────────────────────
|
|
390
390
|
//
|
|
391
391
|
// Heuristic:
|
|
392
|
-
// -
|
|
393
|
-
//
|
|
394
|
-
// -
|
|
395
|
-
//
|
|
392
|
+
// - If an external pool initiates the process by messaging the
|
|
393
|
+
// organization's start event, promote it to the top.
|
|
394
|
+
// - Otherwise preserve the modeler's input order (the natural expectation
|
|
395
|
+
// when the start event is a plain origin with no incoming message).
|
|
396
396
|
function orderPools(m) {
|
|
397
397
|
const initiators = new Set();
|
|
398
398
|
const orgStartEvents = new Set();
|
|
@@ -409,16 +409,9 @@ function orderPools(m) {
|
|
|
409
409
|
initiators.add(mf.fromPool);
|
|
410
410
|
}
|
|
411
411
|
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
const
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
primary.push(p);
|
|
418
|
-
else if (p.type === "organization")
|
|
419
|
-
org.push(p);
|
|
420
|
-
else
|
|
421
|
-
supporting.push(p);
|
|
422
|
-
}
|
|
423
|
-
return [...primary, ...org, ...supporting];
|
|
412
|
+
if (initiators.size === 0)
|
|
413
|
+
return [...m.pools]; // respect input order
|
|
414
|
+
const primary = m.pools.filter((p) => initiators.has(p.id));
|
|
415
|
+
const rest = m.pools.filter((p) => !initiators.has(p.id));
|
|
416
|
+
return [...primary, ...rest];
|
|
424
417
|
}
|
package/dist/bpmn/svg.js
CHANGED
|
@@ -80,6 +80,24 @@ export function renderPool(pool) {
|
|
|
80
80
|
const contentW = pool.w - headerW;
|
|
81
81
|
const labelCx = headerX + headerW / 2;
|
|
82
82
|
const labelCy = pool.y + pool.h / 2;
|
|
83
|
+
// Rotated pool labels run vertically, so their available length is the pool
|
|
84
|
+
// HEIGHT. Short (external-empty) pools clip long names — wrap to fit, and
|
|
85
|
+
// render the lines side by side across the header width.
|
|
86
|
+
const maxChars = Math.max(4, Math.floor((pool.h - 14) / 7));
|
|
87
|
+
const nameLines = wrapLabel(pool.name, maxChars, 3);
|
|
88
|
+
const lines = nameLines.length ? nameLines : [pool.name];
|
|
89
|
+
const nameFont = lines.length >= 3 ? 10 : lines.length === 2 ? 11 : 12;
|
|
90
|
+
const nameGap = nameFont + 1;
|
|
91
|
+
const nameSvg = lines
|
|
92
|
+
.map((ln, i) => {
|
|
93
|
+
const lx = labelCx + (i - (lines.length - 1) / 2) * nameGap;
|
|
94
|
+
return `<text x="${lx}" y="${labelCy}" text-anchor="middle"
|
|
95
|
+
dominant-baseline="middle"
|
|
96
|
+
transform="rotate(-90, ${lx}, ${labelCy})"
|
|
97
|
+
fill="#ffffff" font-size="${nameFont}" font-weight="600"
|
|
98
|
+
direction="rtl">${escapeXml(ln)}</text>`;
|
|
99
|
+
})
|
|
100
|
+
.join("\n ");
|
|
83
101
|
return `
|
|
84
102
|
<!-- pool: ${escapeXml(pool.poolId)} -->
|
|
85
103
|
<g class="bpmn-pool" data-pool="${escapeXml(pool.poolId)}">
|
|
@@ -87,11 +105,7 @@ export function renderPool(pool) {
|
|
|
87
105
|
fill="${bodyFill}" stroke="${bodyStroke}" stroke-width="1.5"/>
|
|
88
106
|
<rect x="${headerX}" y="${pool.y}" width="${headerW}" height="${pool.h}"
|
|
89
107
|
fill="${headerFill}" stroke="${bodyStroke}" stroke-width="1.5"/>
|
|
90
|
-
|
|
91
|
-
dominant-baseline="middle"
|
|
92
|
-
transform="rotate(-90, ${labelCx}, ${labelCy})"
|
|
93
|
-
fill="#ffffff" font-size="12" font-weight="600"
|
|
94
|
-
direction="rtl">${escapeXml(pool.name)}</text>
|
|
108
|
+
${nameSvg}
|
|
95
109
|
<line x1="${contentX}" y1="${pool.y}" x2="${contentX}" y2="${pool.y + pool.h}"
|
|
96
110
|
stroke="${bodyStroke}" stroke-width="1"/>
|
|
97
111
|
</g>`;
|
package/package.json
CHANGED
|
@@ -459,6 +459,7 @@ When splitting (§5), generate one `<svg id="svg-part-N">` per part. Split `CLAS
|
|
|
459
459
|
## 10. Output
|
|
460
460
|
|
|
461
461
|
- Save as `[system_name]_class_diagram.html`
|
|
462
|
+
- **Visual verification (required) — a loop, not a one-shot.** Structural validity ≠ visual validity. If a browser is available, render the HTML to an image, inspect it, and **fix → re-render → repeat until visually clean**. Scan every pass for: box overlaps; boxes off-canvas/clipped; a **multiplicity or role label landing inside a box** or on a line; **any line crossing through a foreign box**; the association-class tether hitting the wrong association; enum boxes overlapping. Do not report the diagram as done until a rendered pass is clean.
|
|
462
463
|
- After saving, briefly state: number of classes, enumerations, relationships, whether split (and why), whether VP export is included
|
|
463
464
|
|
|
464
465
|
---
|
|
@@ -44,7 +44,7 @@ Two compartments separated by a horizontal line:
|
|
|
44
44
|
- `exit /` actions on leaving
|
|
45
45
|
- `do /` ongoing activity while in state
|
|
46
46
|
|
|
47
|
-
Multiple activity lines in one compartment are fine.
|
|
47
|
+
Multiple activity lines in one compartment are fine — but that means different *kinds* of lines (`entry /`, `exit /`, `do /`). Each kind appears **at most once per state**: a state has a single entry behavior, so multiple entry actions are written in the one `entry /` clause separated by `;`, never as a repeated `entry /` line.
|
|
48
48
|
|
|
49
49
|
## Layout Rules (from lectures)
|
|
50
50
|
|
|
@@ -51,6 +51,7 @@ The shared files prepended to this prompt define the layout recipes, model shape
|
|
|
51
51
|
2. **Activity compartment** — always present; minimum content is `entry / setStatus('SCREAMING_SNAKE_CASE')`
|
|
52
52
|
- `setStatus()` is required in every state including composite states and archive states — it represents the object's tracked status in the implementation
|
|
53
53
|
- Additional compartment lines: `entry / action`, `exit / action`, `do / activity`
|
|
54
|
+
- **At most one `entry /` clause per state** (same for `exit /`). UML allows a single entry behavior; multiple entry actions go in that one clause, separated by `;` (wrap to an indented continuation line if too wide) — never write a second `entry /` line
|
|
54
55
|
- Never produce a state with only a name and no compartment
|
|
55
56
|
|
|
56
57
|
### Transitions
|
|
@@ -257,6 +258,7 @@ Include at the bottom of every SVG:
|
|
|
257
258
|
## 11. Output
|
|
258
259
|
|
|
259
260
|
- Save as `[entity_name]_state_diagram.html`
|
|
261
|
+
- **Visual verification (required) — a loop, not a one-shot.** Structural validity ≠ visual validity. If a browser is available, render the HTML, inspect it, and **fix → re-render → repeat until visually clean**. Scan for: state-box overlaps; transition **labels/guards landing on a box or on another line**; arrows crossing through a foreign state; the initial/final markers misplaced; self-transitions unreadable. Confirm the lifecycle reads as **non-linear** (branches + returns), not a straight line. Don't report done until a rendered pass is clean.
|
|
260
262
|
- Briefly state: entity modeled, state count, transition count, composite states, whether split
|
|
261
263
|
|
|
262
264
|
---
|
|
@@ -907,6 +907,9 @@ The validator runs locally (no API cost) and catches what the §4 and CR gates c
|
|
|
907
907
|
If the response is `✗ Model invalid`, fix every listed error and call the validator again. **Do not write the HTML file until the validator returns `✓ Model valid`.**
|
|
908
908
|
|
|
909
909
|
After the validator passes, save the HTML as `[system_name]_use_case_diagram.html`.
|
|
910
|
+
|
|
911
|
+
**Visual verification (required) — a loop, not a one-shot.** The validator passing is necessary but NOT sufficient: it does not catch layout problems. If a browser is available, render the HTML and inspect it, then **fix → re-render → repeat until visually clean**. Check **both tabs** (toggle which `.diagram-part` is `hidden`) and open at least one UC modal to confirm the wireframe renders. Scan every pass for: ellipse **overlaps**; actors too close (min ~200px); actor figure detached from its own line; a UC crowded into a **center column** (usually a recipient-only human actor on a system-initiated UC — remove it per §4.1); wide ellipses colliding with the boundary title bar; timing/label text on top of a line. Do not report the diagram as done until a rendered pass of each tab is clean.
|
|
912
|
+
|
|
910
913
|
Briefly report: actor count, use case count, include/extend count, whether split, and any warnings the validator surfaced.
|
|
911
914
|
|
|
912
915
|
---
|