sad-mcp 0.1.3 → 0.1.4

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 ADDED
@@ -0,0 +1,85 @@
1
+ # sad-mcp
2
+
3
+ MCP server that gives students access to **Software Analysis and Design** course materials through Claude Desktop. Materials are served from a shared Google Drive folder.
4
+
5
+ ## What it does
6
+
7
+ - Exposes course materials (lectures, transcripts, exams) as MCP **resources**
8
+ - Provides `search_materials` and `list_materials` **tools** for Claude to query course content
9
+ - Extracts text from PPTX, PDF, DOCX, XLSX, and plain text files
10
+ - Caches files locally to avoid repeated downloads
11
+ - Tracks anonymous usage for research purposes
12
+
13
+ ## Student setup
14
+
15
+ Add to your Claude Desktop configuration (`claude_desktop_config.json`):
16
+
17
+ ```json
18
+ {
19
+ "mcpServers": {
20
+ "sad-course": {
21
+ "command": "npx",
22
+ "args": ["-y", "sad-mcp@latest"]
23
+ }
24
+ }
25
+ }
26
+ ```
27
+
28
+ On Windows, use the full path to `npx.cmd`:
29
+
30
+ ```json
31
+ {
32
+ "mcpServers": {
33
+ "sad-course": {
34
+ "command": "C:\\Program Files\\nodejs\\npx.cmd",
35
+ "args": ["-y", "sad-mcp@latest"]
36
+ }
37
+ }
38
+ }
39
+ ```
40
+
41
+ On first run, a browser window will open for Google authentication. Sign in with your **@post.bgu.ac.il** account. After that, the server connects automatically.
42
+
43
+ ## Tools
44
+
45
+ | Tool | Description |
46
+ |------|-------------|
47
+ | `search_materials(query)` | Full-text search across all course materials |
48
+ | `list_materials(category?)` | List available materials, optionally filtered by `lectures`, `transcripts`, `exams`, or `all` |
49
+
50
+ ## Resources
51
+
52
+ All extractable files from the course Google Drive folder are exposed as MCP resources with URIs like `sad://lectures/filename.pptx` or `sad://transcripts/filename.txt`. Claude can read these directly.
53
+
54
+ ## Local data
55
+
56
+ The server stores data in `~/.sad-mcp/`:
57
+
58
+ | File | Purpose |
59
+ |------|---------|
60
+ | `tokens.json` | Google OAuth refresh token |
61
+ | `anonymous-id.txt` | Random UUID for usage tracking |
62
+ | `usage-log.jsonl` | Local usage event log |
63
+ | `cache/` | Downloaded file cache (1-hour TTL) |
64
+ | `cache-index.json` | Cache metadata |
65
+
66
+ ## Development
67
+
68
+ ```bash
69
+ npm install
70
+ npm run build # compile TypeScript
71
+ npm run dev # watch mode
72
+ ```
73
+
74
+ ## Publishing
75
+
76
+ ```bash
77
+ # bump version in package.json
78
+ npm publish
79
+ ```
80
+
81
+ Students get the latest version automatically via `npx -y sad-mcp@latest`.
82
+
83
+ ## License
84
+
85
+ MIT
package/dist/index.js CHANGED
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
3
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
- import { registerResourceHandlers } from "./resources.js";
5
4
  import { registerToolHandlers } from "./tools.js";
5
+ import { registerPromptHandlers } from "./prompts.js";
6
6
  import { trackServerStart } from "./tracking.js";
7
7
  async function main() {
8
8
  // Connect to Claude Desktop IMMEDIATELY — no blocking auth here
9
9
  // Auth happens lazily on first Drive API call
10
- const server = new Server({ name: "sad-mcp", version: "0.1.3" }, {
10
+ const server = new Server({ name: "sad-mcp", version: "0.1.4" }, {
11
11
  capabilities: {
12
- resources: {},
13
12
  tools: {},
13
+ prompts: {},
14
14
  },
15
15
  });
16
- registerResourceHandlers(server);
17
16
  registerToolHandlers(server);
17
+ registerPromptHandlers(server);
18
18
  trackServerStart();
19
19
  const transport = new StdioServerTransport();
20
20
  await server.connect(transport);
@@ -0,0 +1,2 @@
1
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
+ export declare function registerPromptHandlers(server: Server): void;
@@ -0,0 +1,56 @@
1
+ import { ListPromptsRequestSchema, GetPromptRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
2
+ import { readFileSync } from "fs";
3
+ import { join, dirname } from "path";
4
+ import { fileURLToPath } from "url";
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = dirname(__filename);
7
+ const SKILLS = [
8
+ {
9
+ id: "uml-class-diagram",
10
+ name: "UML Class Diagram",
11
+ description: "Create professional UML class diagrams as interactive HTML/SVG files",
12
+ },
13
+ {
14
+ id: "uml-state-diagram",
15
+ name: "UML State Diagram",
16
+ description: "Create professional UML state/statechart diagrams as interactive HTML/SVG files",
17
+ },
18
+ {
19
+ id: "uml-use-case-diagram",
20
+ name: "UML Use Case Diagram",
21
+ description: "Create professional UML use case diagrams as interactive HTML/SVG files",
22
+ },
23
+ {
24
+ id: "bpmn-diagram",
25
+ name: "BPMN Diagram",
26
+ description: "Create BPMN business process diagrams as interactive HTML/SVG files",
27
+ },
28
+ ];
29
+ function loadSkill(skillId) {
30
+ const skillsDir = join(__dirname, "..", "skills");
31
+ return readFileSync(join(skillsDir, skillId, "SKILL.md"), "utf-8");
32
+ }
33
+ export function registerPromptHandlers(server) {
34
+ server.setRequestHandler(ListPromptsRequestSchema, async () => ({
35
+ prompts: SKILLS.map((skill) => ({
36
+ name: skill.id,
37
+ description: skill.description,
38
+ })),
39
+ }));
40
+ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
41
+ const skill = SKILLS.find((s) => s.id === request.params.name);
42
+ if (!skill) {
43
+ throw new Error(`Unknown skill: ${request.params.name}`);
44
+ }
45
+ const content = loadSkill(skill.id);
46
+ return {
47
+ description: skill.description,
48
+ messages: [
49
+ {
50
+ role: "user",
51
+ content: { type: "text", text: content },
52
+ },
53
+ ],
54
+ };
55
+ });
56
+ }
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "sad-mcp",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "MCP server for Software Analysis and Design course materials at BGU",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "sad-mcp": "dist/index.js"
8
8
  },
9
9
  "files": [
10
- "dist"
10
+ "dist",
11
+ "skills"
11
12
  ],
12
13
  "scripts": {
13
14
  "build": "tsc",
@@ -0,0 +1,247 @@
1
+ ---
2
+ name: bpmn-diagram
3
+ description: Create BPMN (Business Process Model and Notation) diagrams as interactive HTML/SVG files. Use this skill when the user asks to create, model, or visualize a business process, workflow diagram, BPMN diagram, or process map. Handles Hebrew RTL processes, swim lanes, pools, gateways, data objects, data stores, message flows, and intermediate events. Outputs a single self-contained HTML file with embedded SVG.
4
+ ---
5
+
6
+ # BPMN Diagram Creation Skill
7
+
8
+ This skill creates professional, standards-compliant BPMN diagrams rendered as interactive HTML files with embedded SVG. The diagrams support Hebrew (RTL) and English text, and follow BPMN 2.0 notation with BPMN 1.1-style intermediate events (plain double circles without internal icons).
9
+
10
+ ## When to Use
11
+
12
+ - User asks to create a BPMN diagram, process model, or workflow diagram
13
+ - User describes a business process and wants it visualized
14
+ - User provides a process narrative in any language and wants a BPMN representation
15
+ - User asks to model a process with swim lanes, pools, gateways, or data flows
16
+
17
+ ## Process Analysis — Before Drawing
18
+
19
+ Before writing any SVG code, analyze the process description to identify:
20
+
21
+ 1. **Participants**: Who are the actors? Determine if they are internal (lanes in the same pool) or external (separate pools)
22
+ - External participants (customers, patients, citizens) → **separate pool** with message flows
23
+ - Internal roles within the same organization → **lanes** within one pool
24
+ 2. **Activities/Tasks**: List every action/task mentioned
25
+ 3. **Decision Points**: Identify every conditional branch (if/else, exists/doesn't exist)
26
+ 4. **Data**: What information is created, read, updated, or stored?
27
+ 5. **Handoffs**: Where does work pass between participants? These become message flows between pools or sequence flows between lanes
28
+ 6. **Waiting Points**: Is any participant passively waiting? Use intermediate events, not regular tasks
29
+ 7. **Data Persistence**: If the process description mentions a "system" or implies that data is stored, read, or updated across multiple steps or participants — model a Data Store (DB). Connect it with data associations to every task that reads from or writes to it. Do NOT substitute a lightweight Data Object when persistent shared storage is implied. A system = a data store.
30
+ 8. **Complete Each Participant's Flow**: Every pool must have its own complete internal sequence flow (start → tasks → end), even for external parties. If the description says "Company X will handle the complaint," model the full handling sequence inside that pool (receive → process → respond → close), not just the first step. Never collapse an external participant's process into a single task or annotation.
31
+ 9. **Bidirectional Communication**: When one participant sends something to another, check: does the receiver send something back? Every message flow that triggers a response must have a corresponding return message flow. Model both directions explicitly. Common pairs: request→acknowledgment, notification→confirmation, complaint→response.
32
+ 10. **Implied Activities**: Read the description for activities that are described but not explicitly named as "tasks." Phrases like "she can and is expected to be in phone contact" or "will coordinate directly" describe real activities that should be modeled as tasks, NOT as text annotations. Annotations are only for meta-information that clarifies context but isn't an executable step.
33
+
34
+ ## Architecture & Layout Rules
35
+
36
+ ### Pools and Lanes
37
+
38
+ - **External participants** (e.g., patient, customer, citizen) get their own **pool** at the top of the diagram
39
+ - Use a distinct color scheme for the external pool header (e.g., brown) to differentiate from the organization pool (dark gray)
40
+ - External pool tasks use a warm color (e.g., orange `#fff3e0` fill, `#e65100` stroke)
41
+ - **Internal roles** within the organization are modeled as **lanes** within the organization pool
42
+ - Each lane gets a labeled sidebar and a subtle background tint
43
+ - Separate lanes with dashed divider lines
44
+ - Pool headers are vertical text bars on the left side of the pool
45
+
46
+ ### Color Scheme by Participant Type
47
+
48
+ | Element | Fill | Stroke |
49
+ |---------|------|--------|
50
+ | External participant tasks | `#fff3e0` | `#e65100` |
51
+ | Reception/admin tasks | `#e3f2fd` | `#1976d2` |
52
+ | Clinical/operational tasks | `#f3e5f5` | `#7b1fa2` |
53
+ | XOR Gateways | `#fff8e1` | `#f9a825` |
54
+ | Start event | `#e8f5e9` | `#2e7d32` |
55
+ | End event | `#ffebee` | `#c62828` |
56
+ | Data objects | `#fff` | `#1565c0` |
57
+ | Data stores | `#fff` | `#2e7d32` |
58
+
59
+ ### Pool Ordering — Optimal Layout
60
+
61
+ When multiple external pools exist, order pools to **minimize message flow crossing distance**:
62
+
63
+ - Place the **primary actor** (the one who initiates and interacts with multiple parties) in the **middle**, not at the top
64
+ - Place pools they interact with **above and below** so message flows go in both directions naturally
65
+ - Rule of thumb: Count message flows between each pair of pools. Adjacent pools should be the pairs with the most message flows between them
66
+
67
+ Example: If a Resident interacts with both a Delivery Company and a Development Company → place Delivery Company on top, Resident in the middle, Development Company on the bottom.
68
+
69
+ ### Flow Types
70
+
71
+ - **Sequence flows** (within a pool): Solid lines with filled arrowheads (`#546e7a`)
72
+ - **Message flows** (between pools): Dashed lines (`stroke-dasharray: 10 5`) with open circle at source and filled arrow at target (`#37474f`)
73
+ - **Data associations**: Dashed lines (`stroke-dasharray: 4 3`) with small arrowheads, colored by type:
74
+ - Data object associations: `#7986cb`
75
+ - Data store associations: `#4caf50`
76
+
77
+ ## BPMN Element Standards
78
+
79
+ ### Gateways — CRITICAL RULE
80
+
81
+ **Every gateway — both split AND merge/join — MUST display the X marker (for XOR) or + marker (for AND/parallel).** Merge gateways are never left as blank diamonds. This is a non-negotiable requirement.
82
+
83
+ ```svg
84
+ <!-- XOR Gateway template (both split and merge) -->
85
+ <rect x="X" y="Y" width="34" height="34" class="gateway" transform="rotate(45, CX, CY)"/>
86
+ <line x1="CX-7" y1="CY-10" x2="CX+7" y2="CY+10" class="gateway-x"/>
87
+ <line x1="CX+7" y1="CY-10" x2="CX-7" y2="CY+10" class="gateway-x"/>
88
+ ```
89
+
90
+ ### Intermediate Events (Waiting/Catching)
91
+
92
+ Use **BPMN 1.1 style**: plain double circle with NO icon inside. Just two concentric circles.
93
+
94
+ ```svg
95
+ <!-- Intermediate event — plain double circle -->
96
+ <circle cx="X" cy="Y" r="16" fill="#fff" stroke="#1565c0" stroke-width="2"/>
97
+ <circle cx="X" cy="Y" r="12" fill="none" stroke="#1565c0" stroke-width="1.2"/>
98
+ ```
99
+
100
+ Use intermediate events (not tasks) when a participant is passively waiting for a signal, message, or trigger from another participant.
101
+
102
+ ### Data Objects vs Data Stores — MUST DISTINGUISH
103
+
104
+ These are two different BPMN artifacts and must be visually distinct:
105
+
106
+ **Data Objects** (folded-corner document icon, blue):
107
+ - Represent a specific piece of data flowing through the process (e.g., "פרטי תינוק", "סיכום ביקור", "הערת מעקב")
108
+ - Drawn as a rectangle with a folded top-right corner
109
+
110
+ ```svg
111
+ <!-- Data Object template (w≈34, h≈38) -->
112
+ <path d="M X,Y L X+26,Y L X+34,Y+8 L X+34,Y+38 L X,Y+38 Z" class="data-object-shape"/>
113
+ <path d="M X+26,Y L X+26,Y+8 L X+34,Y+8" class="data-object-fold"/>
114
+ ```
115
+
116
+ **Data Stores** (cylinder icon, green):
117
+ - Represent persistent storage / databases (e.g., "מאגר כרטיסי תינוקות", "מאגר מדדים")
118
+ - Drawn as a cylinder (two ellipses connected by vertical lines)
119
+
120
+ ```svg
121
+ <!-- Data Store template -->
122
+ <ellipse cx="CX" cy="TOP" rx="28" ry="8" class="data-store-body"/>
123
+ <path d="M CX-28,TOP L CX-28,BOTTOM" fill="none" stroke="#2e7d32" stroke-width="1.3"/>
124
+ <path d="M CX+28,TOP L CX+28,BOTTOM" fill="none" stroke="#2e7d32" stroke-width="1.3"/>
125
+ <ellipse cx="CX" cy="BOTTOM" rx="28" ry="8" class="data-store-body"/>
126
+ ```
127
+
128
+ ### Data Artifact Placement
129
+
130
+ - Place data objects **above** or **below** their associated task, never overlapping flow lines
131
+ - Place data objects to the **left** of a task if vertical placement would cross flow paths
132
+ - Data stores typically go below their associated tasks
133
+ - **Never** place data artifacts in a location where their association lines cross or overlap with sequence flow arrows
134
+
135
+ ## Arrow Routing — CRITICAL
136
+
137
+ The most important visual quality rule: **arrows must never be ambiguous**.
138
+
139
+ ### Split-Merge Pattern (Two Outcome Paths)
140
+
141
+ When a gateway splits into two paths (e.g., "תקין" vs "דורש מעקב") and then merges:
142
+
143
+ 1. Place the **YES task** above the gateway's horizontal center line
144
+ 2. Place the **NO task** below the gateway's horizontal center line
145
+ 3. Place the **merge gateway** clearly to the right of BOTH tasks
146
+ 4. Route the YES path: task → **right** → **down** into merge gateway (entering from top)
147
+ 5. Route the NO path: task → **right** → **up** into merge gateway (entering from bottom)
148
+ 6. From the merge gateway, route a **single clean vertical line down** to the next task
149
+
150
+ **The merge area must have clear visual separation between all paths. No path should overlap another.**
151
+
152
+ ### General Routing Rules
153
+
154
+ - Prefer orthogonal (right-angle) routing over diagonal lines
155
+ - Leave at least 30px spacing between parallel flow lines
156
+ - When routing a flow from one lane to another, use a clear vertical drop/rise
157
+ - Label YES/NO (כן/לא) near the gateway, not at the end of the path
158
+ - Flow labels should not overlap with other elements
159
+
160
+ ## Modeling Rejection/Retry Loops
161
+
162
+ When a process includes an approval step where the participant can reject:
163
+
164
+ 1. Model the **rejection action** as an explicit task in the rejecting participant's pool (e.g., "שליחת ביטול סגירה"), not just a gateway output
165
+ 2. After rejection, model what the rejecting participant **does next** — typically a waiting intermediate event (e.g., waiting for follow-up contact)
166
+ 3. In the receiving pool, model the **response to rejection** as a concrete task sequence (e.g., "contact customer" → "decide next step")
167
+ 4. Loop-back arrows should return to the earliest meaningful re-entry point in the process, not to an arbitrary task
168
+
169
+ ## Typography & Hebrew Support
170
+
171
+ - Use `Noto Sans Hebrew` (imported from Google Fonts) for all text
172
+ - Set `lang="he"` and `dir="rtl"` on the HTML element
173
+ - Task text: 11.5px, font-weight 500, centered in the task box
174
+ - Gateway labels: 10.5px, font-weight 400, positioned above the diamond
175
+ - Data labels: 9.5px, font-weight 500
176
+ - Flow labels (כן/לא): 10px
177
+
178
+ ## File Structure
179
+
180
+ Output a single self-contained HTML file with:
181
+
182
+ 1. **Header bar**: Gradient background with process title in Hebrew + English subtitle
183
+ 2. **Legend**: Horizontal bar showing all BPMN symbols used in the diagram (start, end, task, XOR gateway, intermediate event, data object, data store, message flow)
184
+ 3. **SVG canvas**: The full BPMN diagram in a scrollable wrapper
185
+ 4. **SVG definitions**: Drop shadow filters, arrow markers (sequence, message, data association)
186
+
187
+ ### SVG Sizing
188
+
189
+ - Width: 1700–1800px typical (allow overflow scroll)
190
+ - Height: Scale based on number of pools and lanes (~130px per external pool, ~250px per lane, plus spacing for data artifacts)
191
+ - Use `viewBox` matching width/height for proper scaling
192
+
193
+ ## Iterative Refinement Checklist
194
+
195
+ After generating the initial diagram, verify:
196
+
197
+ - [ ] Every gateway (split AND merge) has an X or + symbol
198
+ - [ ] No arrow paths overlap or cross ambiguously
199
+ - [ ] Data objects (📄) and data stores (🗄️) use different icons
200
+ - [ ] External participants are in separate pools with message flows
201
+ - [ ] Passive waiting uses intermediate events, not regular tasks
202
+ - [ ] Flow labels (כן/לא) are clearly positioned near their gateway
203
+ - [ ] The legend includes every symbol type used in the diagram
204
+ - [ ] Data artifacts don't overlap with sequence flow paths
205
+ - [ ] Every pool has a complete internal flow (start → ... → end), not just a single task
206
+ - [ ] A Data Store is modeled if the process mentions a "system" or database
207
+ - [ ] Every message flow that expects a response has a return message flow
208
+ - [ ] Phone calls, emails, and direct contacts mentioned in the description are modeled as tasks, not annotations
209
+ - [ ] After a rejection/refusal gateway, the rejecting participant's subsequent state (waiting/action) is explicitly modeled
210
+ - [ ] Pool ordering minimizes message flow crossing distance
211
+
212
+ ## Example Process Categories
213
+
214
+ This skill handles processes such as:
215
+ - Healthcare workflows (e.g., Tipat Halav clinic visits, hospital admissions)
216
+ - Government/municipal service processes
217
+ - Customer service and support flows
218
+ - Order fulfillment and logistics
219
+ - Employee onboarding
220
+ - Academic/educational administration processes
221
+
222
+ The skill works for any domain — adapt the color scheme and terminology to match the context.
223
+
224
+ ## Hebrew Language Guidelines (שפה מגדרית נייטרלית)
225
+
226
+ When labels, names, actors, roles, or any text in the diagram are written in Hebrew, follow these rules:
227
+
228
+ ### Use Male Form as Default
229
+ Always use the **male grammatical form** (זכר) when referring to people, roles, actors, classes, or participants — even when the role is traditionally associated with a specific gender.
230
+
231
+ **Examples of correct usage:**
232
+ - ✅ רופא (not אחות for a nurse role — use אח)
233
+ - ✅ אח (nurse, male form)
234
+ - ✅ מטופל (not מטופלת)
235
+ - ✅ לקוח (not לקוחה)
236
+ - ✅ מנהל (not מנהלת)
237
+ - ✅ עובד (not עובדת)
238
+ - ✅ משתמש (not משתמשת)
239
+ - ✅ סטודנט (not סטודנטית)
240
+
241
+ **Examples of stereotypic writing to avoid:**
242
+ - ❌ רופא ואחות — implies doctor=male, nurse=female
243
+ - ❌ מזכירה — use מזכיר instead
244
+ - ❌ אחות — use אח instead
245
+
246
+ ### Rule Summary
247
+ > When in doubt, use the male form. This ensures gender neutrality and avoids reinforcing occupational gender stereotypes in diagram content.
@@ -0,0 +1,227 @@
1
+ ---
2
+ name: uml-class-diagram
3
+ description: >
4
+ Create professional UML 1.1 class diagrams as interactive HTML/SVG files.
5
+ Use this skill whenever the user asks to draw, create, design, or generate a
6
+ class diagram, UML diagram, object model, or domain model — even if they just
7
+ say "model these classes" or "show me the relationships between these entities".
8
+ Also trigger when the user uploads a document (exam, spec, requirements) and
9
+ asks to extract or design a class diagram from it. Always produces a
10
+ self-contained HTML file with embedded SVG, clean two-color styling, and an
11
+ optional interactive composition toggle panel.
12
+ ---
13
+
14
+ # UML 1.1 Class Diagram Skill
15
+
16
+ Produce a clean, exam-ready UML 1.1 class diagram as a single self-contained HTML file with embedded SVG.
17
+
18
+ ---
19
+
20
+ ## 1. Gather Requirements First
21
+
22
+ Before drawing, extract or confirm:
23
+
24
+ | Question | Why it matters |
25
+ |---|---|
26
+ | What are the core **entities/classes**? | Determines layout |
27
+ | What **attributes** does each class have (name, type)? | Fills compartments |
28
+ | What **methods** does each class have? | Third compartment |
29
+ | What **enumerations** exist? | Grouped separately |
30
+ | What are the **relationships** and their **multiplicities**? | Association lines |
31
+ | Is the diagram for **teaching** (simplified) or production? | Affects notation choices |
32
+ | Should the user be able to **toggle compositions** interactively? | Adds control panel |
33
+ | **Should roles use enumerations or inheritance?** | Prefer enum; document reasoning if abstract classes are used |
34
+
35
+ If the user provides a document (PDF, image, exam question), read it carefully and extract all of the above before drawing.
36
+
37
+ ---
38
+
39
+ ## 2. Notation Rules (UML 1.1 Style)
40
+
41
+ ### Classes
42
+ - Three compartments: **Name** (blue header), **Attributes**, **Methods** (italic)
43
+ - Attribute format: `+ name : Type` or `+ name : Type[ ]` for arrays
44
+ - Method format (italic, blue): `+ methodName(param : Type) : ReturnType`
45
+ - **Stereotype handling**: When a class has a stereotype (e.g., `«association class»`), increase the header height to at least 38px (from default 32px) so that BOTH the stereotype text AND the class name are fully readable. The stereotype goes on the first line (smaller font, ~9px), the class name on the second line (bold, normal size).
46
+
47
+ ### Enumerations
48
+ - Stereotype header: `«enumeration»`
49
+ - Gray dashed border, gray header — visually distinct from classes
50
+ - List values only (no attributes/methods)
51
+ - Group all enumerations on the **right side** of the diagram, separated by a vertical dashed line
52
+ - **NO dependency lines from enums to classes** — do NOT draw dashed `«uses»` arrows connecting enumerations to the classes that reference them. The enum zone grouping is sufficient; dependency lines add clutter without information.
53
+
54
+ ### Association Lines
55
+ - **Default: plain lines, no arrowheads, no diamonds** — this is the recommended starting point for teaching contexts
56
+ - Multiplicity at **both ends**: `1`, `0..*`, `1..*`, `0..1`
57
+ - Role label mid-line (rotated if diagonal)
58
+ - **Composition diamonds** (◆, filled, at the "whole" end): only add when explicitly requested or via the interactive toggle panel
59
+
60
+ ### Association Classes
61
+ - Mark with `«association class»` stereotype when a relationship itself has attributes
62
+ - **CRITICAL**: An association class is drawn as a regular class box connected by a **dashed line to the midpoint of the association line** it describes. NEVER draw it as a standalone class connected by a regular dependency arrow — that is incorrect UML notation.
63
+ - The dashed line should be perpendicular to the association line where possible, connecting from the center of the association to the top or bottom of the association class box.
64
+
65
+ ---
66
+
67
+ ## 3. Abstraction vs. Role Enum Decision
68
+
69
+ When modeling roles (e.g., different user types, participant types, staff types):
70
+
71
+ ### Default: Use a Role Enumeration
72
+ - Create a single class with a `role: RoleType` attribute
73
+ - Add a `«enumeration» RoleType` with the possible roles
74
+ - This is simpler, avoids inheritance, and matches how most systems store data
75
+
76
+ ### When Abstract Classes ARE Justified
77
+ Use inheritance ONLY when subtypes have **genuinely different attributes or methods** — not just different role labels. For example:
78
+ - ✅ `Vehicle` → `Car` (has: numDoors) vs `Truck` (has: payloadCapacity) — different attributes
79
+ - ❌ `Person` → `Doctor` vs `Nurse` — same attributes, different role — use enum instead
80
+
81
+ ### "Why Abstraction?" Explanation Panel
82
+ If abstract classes or inheritance ARE used in a diagram, add a small explanation panel (bottom-left of SVG, light yellow background) titled **"Why Abstraction?"** that lists:
83
+ - Which classes use inheritance and why
84
+ - What distinct attributes/methods each subclass adds
85
+ - This helps students understand the design decision
86
+
87
+ ---
88
+
89
+ ## 4. Layout Strategy
90
+ LEFT ZONE CENTER ZONE RIGHT ZONE
91
+ ───────────── ──────────── ──────────────
92
+ Secondary/ Core domain ENUMERATIONS
93
+ supporting classes (gray, dashed)
94
+ classes (main flow)
95
+
96
+ **Routing rules to avoid line crossings:**
97
+ - Run long associations along a fixed Y above all classes (horizontal routing)
98
+ - Use L-shaped polylines for crossing-prone vertical connections
99
+ - Diagonal lines only for clean point-to-point connections
100
+ - Always verify coordinate math before finalizing paths
101
+ - **Line-through-class-body prevention**: After placing all classes, verify that EVERY association line segment's coordinates do not pass through any class rectangle's bounding box (x, y, x+width, y+height). If a segment overlaps a class body, re-route to a different entry edge (e.g., right side instead of top) or detour around the outside. Never allow a line to visually cross through a class rectangle.
102
+
103
+ ---
104
+
105
+ ## 5. Styling Specification
106
+ Background: #f8fafc with dot-grid pattern (24px, #cbd5e1 dots r=0.8)
107
+ Class fill: white, border #3b82f6 (2px), header #1e40af
108
+ Enum fill: #f8fafc, border #94a3b8 dashed (5,3), header #475569
109
+ Attribute text: #1e293b, 10.5px
110
+ Method text: #2563eb, 10.5px, italic
111
+ Label text: #64748b, 9.5px
112
+ Multiplicity: #334155, 10px
113
+ Association line: #334155, 1.8px
114
+ Diamond fill: #1e40af (same as class header)
115
+ Font: 'IBM Plex Mono', monospace (load from Google Fonts)
116
+
117
+ ---
118
+
119
+ ## 6. Interactive Composition Toggle (when requested)
120
+
121
+ Add a **left-side control panel** alongside the diagram when the user wants interactive composition selection.
122
+
123
+ ### Panel structure
124
+ - Title: "Composition Toggle"
125
+ - One card per candidate composition relationship
126
+ - Each card includes:
127
+ - Toggle switch (CSS-animated, blue when active)
128
+ - Label: `WholeClass ◆── PartClass`
129
+ - Plain-language explanation of why it qualifies
130
+ - Strength badge: **Strong** (green) or **Moderate** (yellow)
131
+ - "All ◆" and "Clear" buttons at the bottom
132
+
133
+ ### Composition strength criteria
134
+ | Strength | Condition |
135
+ |---|---|
136
+ | **Strong** | Part has no identity or meaning without the whole; should be deleted with it |
137
+ | **Moderate** | Part is created per-whole but references independent entities; borderline |
138
+
139
+ ### Diamond rendering
140
+ - The diamond polygon sits **at the class boundary** (whole end), not floating on the line
141
+ - Diamond points: `(x,y) (x-8, y-4.5) (x-16, y) (x-8, y+4.5)` — adjust for line direction
142
+ - Use CSS `transition: opacity .22s` for smooth toggle
143
+ - Diamonds start hidden (`opacity: 0`) and fade in on toggle
144
+
145
+ ### JavaScript
146
+ ```javascript
147
+ const state = { 'rel-id': false, ... };
148
+ function toggle(id) { state[id] = !state[id]; apply(id); }
149
+ function apply(id) {
150
+ document.getElementById('diamond-' + id)
151
+ .setAttribute('opacity', state[id] ? '1' : '0');
152
+ document.getElementById('btn-' + id)
153
+ .classList.toggle('active', state[id]);
154
+ }
155
+ function setAll(on) {
156
+ Object.keys(state).forEach(id => { state[id] = on; apply(id); });
157
+ }
158
+ ```
159
+
160
+ ---
161
+
162
+ ## 7. HTML File Structure
163
+
164
+ Always produce a single self-contained HTML file with:
165
+ - IBM Plex Mono from Google Fonts
166
+ - Embedded CSS for layout, panel styles, toggle animation
167
+ - SVG diagram with: background + dot grid, zone separator, classes, enumerations, association lines, composition diamonds (opacity:0 default), legend bar
168
+ - Optional sticky composition control panel on the left
169
+ - Optional "Why Abstraction?" panel if inheritance is used
170
+
171
+ ---
172
+
173
+ ## 8. Legend Bar
174
+
175
+ Always include at the bottom of the SVG:
176
+ `[ plain line ] Association [ ◆─── line ] Composition (◆ = whole end) Multiplicity at both ends italic = methods`
177
+
178
+ ---
179
+
180
+ ## 9. Output
181
+
182
+ - Save to `/mnt/user-data/outputs/<system_name>_class_diagram.html`
183
+ - Call `present_files` to share with user
184
+ - Briefly describe: number of classes, enumerations, relationships, whether interactive panel is included
185
+ - Do NOT reproduce the full SVG coordinate listing in chat
186
+
187
+ ---
188
+
189
+ ## 10. Common Pitfalls
190
+
191
+ - **Prefer role enum over abstraction** — always document your reasoning when choosing inheritance
192
+ - **Abstraction panel missing** — if abstract classes exist and the explanation panel is absent, add it
193
+ - **Association class notation** — NEVER draw it as a plain class connected by a dependency arrow; ALWAYS use a dashed line from the midpoint of the association line
194
+ - **Line passing through class body** — ALWAYS check that no polyline segment overlaps a class rectangle. After placing all classes, verify each association line's bounding coordinates do not fall within any class's (x, y, x+w, y+h). If they do, re-route to a different entry edge (e.g. right side instead of top) or detour around the outside.
195
+ - **No enum dependency lines** — do NOT draw dashed arrows from enums to classes; the zone grouping is sufficient
196
+ - **Stereotype readability** — when a class has a stereotype, ensure the header is tall enough (≥38px) for both stereotype and class name to be visible
197
+ - Line crossings: route diagonals carefully; use L-shaped polylines when needed
198
+ - Diamond placement: must sit exactly on the class boundary, not floating
199
+ - Enum grouping: always separate from classes visually
200
+ - Methods italic: never forget — it's the key visual distinction
201
+ - Multiplicity both ends: never leave one end unlabeled
202
+ - Font loading: always include Google Fonts import or fall back to `monospace`
203
+
204
+ ## Hebrew Language Guidelines (שפה מגדרית נייטרלית)
205
+
206
+ When labels, names, actors, roles, or any text in the diagram are written in Hebrew, follow these rules:
207
+
208
+ ### Use Male Form as Default
209
+ Always use the **male grammatical form** (זכר) when referring to people, roles, actors, classes, or participants — even when the role is traditionally associated with a specific gender.
210
+
211
+ **Examples of correct usage:**
212
+ - ✅ רופא (not אחות for a nurse role — use אח)
213
+ - ✅ אח (nurse, male form)
214
+ - ✅ מטופל (not מטופלת)
215
+ - ✅ לקוח (not לקוחה)
216
+ - ✅ מנהל (not מנהלת)
217
+ - ✅ עובד (not עובדת)
218
+ - ✅ משתמש (not משתמשת)
219
+ - ✅ סטודנט (not סטודנטית)
220
+
221
+ **Examples of stereotypic writing to avoid:**
222
+ - ❌ רופא ואחות — implies doctor=male, nurse=female
223
+ - ❌ מזכירה — use מזכיר instead
224
+ - ❌ אחות — use אח instead
225
+
226
+ ### Rule Summary
227
+ > When in doubt, use the male form. This ensures gender neutrality and avoids reinforcing occupational gender stereotypes in diagram content.