sad-mcp 0.1.29 → 0.1.31
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/tools.js +61 -0
- package/package.json +1 -1
- package/skills/bpmn-analysis/SKILL.md +5 -3
- package/skills/bpmn-render/SKILL.md +113 -73
package/dist/tools.js
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
import { ListToolsRequestSchema, CallToolRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
import { readFileSync } from "fs";
|
|
3
|
+
import { join, dirname } from "path";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
2
5
|
import { listAllFiles, downloadFile, categorizeFile } from "./drive.js";
|
|
3
6
|
import { extractText, isExtractable } from "./text-extract.js";
|
|
4
7
|
import { loadTextCache, saveTextEntry } from "./text-cache.js";
|
|
5
8
|
import { trackToolCall } from "./tracking.js";
|
|
9
|
+
const __tools_filename = fileURLToPath(import.meta.url);
|
|
10
|
+
const __tools_dirname = dirname(__tools_filename);
|
|
11
|
+
function loadSkillContent(skillId) {
|
|
12
|
+
const skillsDir = join(__tools_dirname, "..", "skills");
|
|
13
|
+
return readFileSync(join(skillsDir, skillId, "SKILL.md"), "utf-8");
|
|
14
|
+
}
|
|
6
15
|
// In-memory text cache for search (populated from disk cache + fresh extractions)
|
|
7
16
|
const textCache = new Map();
|
|
8
17
|
function isExamFile(file) {
|
|
@@ -225,6 +234,34 @@ export function registerToolHandlers(server) {
|
|
|
225
234
|
required: ["exam_id"],
|
|
226
235
|
},
|
|
227
236
|
},
|
|
237
|
+
{
|
|
238
|
+
name: "bpmn_analysis",
|
|
239
|
+
description: "Analyze a business process description and produce a structured BPMN 1.1 model. Call this tool BEFORE creating any BPMN diagram. Pass the process description and receive analysis instructions. You MUST follow the returned instructions exactly.",
|
|
240
|
+
inputSchema: {
|
|
241
|
+
type: "object",
|
|
242
|
+
properties: {
|
|
243
|
+
process_description: {
|
|
244
|
+
type: "string",
|
|
245
|
+
description: "The full business process description to analyze (in Hebrew or English)",
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
required: ["process_description"],
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
name: "bpmn_render",
|
|
253
|
+
description: "Render a BPMN model as an interactive HTML/SVG diagram. Call this ONLY after the user has reviewed and approved the analysis output from bpmn_analysis, and explicitly asked you to draw/render the diagram. Pass the JSON model from the analysis phase.",
|
|
254
|
+
inputSchema: {
|
|
255
|
+
type: "object",
|
|
256
|
+
properties: {
|
|
257
|
+
model_json: {
|
|
258
|
+
type: "string",
|
|
259
|
+
description: "The JSON model from the bpmn_analysis output (Section 8: מודל JSON)",
|
|
260
|
+
},
|
|
261
|
+
},
|
|
262
|
+
required: ["model_json"],
|
|
263
|
+
},
|
|
264
|
+
},
|
|
228
265
|
],
|
|
229
266
|
}));
|
|
230
267
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
@@ -448,6 +485,30 @@ export function registerToolHandlers(server) {
|
|
|
448
485
|
trackToolCall(name, toolArgs, { success: true, responseChars: fullResponse.length }, Date.now() - startTime);
|
|
449
486
|
return { content: [{ type: "text", text: fullResponse }] };
|
|
450
487
|
}
|
|
488
|
+
if (name === "bpmn_analysis") {
|
|
489
|
+
const processDescription = args.process_description;
|
|
490
|
+
if (!processDescription) {
|
|
491
|
+
return {
|
|
492
|
+
content: [{ type: "text", text: "Error: process_description parameter is required" }],
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
const instructions = loadSkillContent("bpmn-analysis");
|
|
496
|
+
const fullResponse = `${instructions}\n\n---\n\n## Process Description to Analyze\n\n${processDescription}`;
|
|
497
|
+
trackToolCall(name, toolArgs, { success: true, responseChars: fullResponse.length }, Date.now() - startTime);
|
|
498
|
+
return { content: [{ type: "text", text: fullResponse }] };
|
|
499
|
+
}
|
|
500
|
+
if (name === "bpmn_render") {
|
|
501
|
+
const modelJson = args.model_json;
|
|
502
|
+
if (!modelJson) {
|
|
503
|
+
return {
|
|
504
|
+
content: [{ type: "text", text: "Error: model_json parameter is required. Use the JSON model from bpmn_analysis output." }],
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
const instructions = loadSkillContent("bpmn-render");
|
|
508
|
+
const fullResponse = `${instructions}\n\n---\n\n## JSON Model to Render\n\n\`\`\`json\n${modelJson}\n\`\`\``;
|
|
509
|
+
trackToolCall(name, toolArgs, { success: true, responseChars: fullResponse.length }, Date.now() - startTime);
|
|
510
|
+
return { content: [{ type: "text", text: fullResponse }] };
|
|
511
|
+
}
|
|
451
512
|
throw new Error(`Unknown tool: ${name}`);
|
|
452
513
|
});
|
|
453
514
|
}
|
package/package.json
CHANGED
|
@@ -207,11 +207,13 @@ Output the complete structured model as a JSON code block. This is the machine-r
|
|
|
207
207
|
}
|
|
208
208
|
```
|
|
209
209
|
|
|
210
|
-
## After the Analysis
|
|
210
|
+
## After the Analysis — STOP
|
|
211
211
|
|
|
212
|
-
End your response with:
|
|
212
|
+
After outputting the analysis, you MUST stop and wait for user feedback. Do NOT proceed to create a diagram, HTML file, or any visual output. Do NOT call any other tools. End your response with exactly this text:
|
|
213
213
|
|
|
214
|
-
**"זהו הניתוח המבני של התהליך. אפשר לבקש תיקונים או שינויים. כשהמודל מאושר,
|
|
214
|
+
**"זהו הניתוח המבני של התהליך. אפשר לבקש תיקונים או שינויים. כשהמודל מאושר, אמרו ״צייר את הדיאגרמה״ ואצור קובץ BPMN."**
|
|
215
|
+
|
|
216
|
+
Your response ends here. Do not continue.
|
|
215
217
|
|
|
216
218
|
## Hebrew Language Guidelines
|
|
217
219
|
|
|
@@ -1,35 +1,78 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: bpmn-render
|
|
3
|
-
description: "
|
|
3
|
+
description: "Render an approved BPMN structural model as an interactive HTML/SVG file."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# BPMN Rendering
|
|
6
|
+
# BPMN Rendering
|
|
7
7
|
|
|
8
|
-
You have an approved structural model
|
|
8
|
+
You have an approved structural model (the JSON below). Render it as a single self-contained HTML file with embedded SVG.
|
|
9
9
|
|
|
10
|
-
**Every participant, task, gateway, data store, data object, and flow from the
|
|
10
|
+
**Every participant, task, gateway, data store, data object, and flow from the model MUST appear in the SVG. Do not add or remove elements. The header pool/lane count MUST match the actual diagram.**
|
|
11
11
|
|
|
12
|
-
## NON-NEGOTIABLE
|
|
12
|
+
## NON-NEGOTIABLE RULES
|
|
13
13
|
|
|
14
|
-
1. **GATEWAYS**: The diamond contains ONLY
|
|
14
|
+
1. **GATEWAYS**: The diamond contains ONLY a marker symbol. NEVER text inside. Labels go ABOVE the diamond. Every gateway (split AND merge) must show its marker.
|
|
15
15
|
|
|
16
|
-
2. **EXTERNAL
|
|
16
|
+
2. **EXTERNAL PARTICIPANT POOLS**: Separate pool rectangles with message flows (dashed). NOT lanes.
|
|
17
17
|
|
|
18
|
-
3. **
|
|
18
|
+
3. **EMPTY POOLS** (external participants with no internal tasks): Message flows connect to/from the **pool border itself** — NOT to any element inside. The pool is just a labeled rectangle. No start/end events inside empty pools.
|
|
19
19
|
|
|
20
|
-
4. **
|
|
20
|
+
4. **DATA STORES** appear as cylinders with data association lines to their tasks.
|
|
21
|
+
|
|
22
|
+
5. **NO ELEMENTS ON LANE BOUNDARIES**: Every element fully inside one lane, centered vertically.
|
|
23
|
+
|
|
24
|
+
6. **HEADER ACCURACY**: The header must show the correct count of pools and lanes matching the actual diagram. Count external pools + organization pool.
|
|
25
|
+
|
|
26
|
+
7. **NO LEGEND**: Do not include a legend section. Students know BPMN notation.
|
|
27
|
+
|
|
28
|
+
## Gateway Marker Styling
|
|
29
|
+
|
|
30
|
+
Gateway markers must be clean and visually prominent. Use SVG paths, not text characters:
|
|
31
|
+
|
|
32
|
+
### XOR Gateway — bold X
|
|
33
|
+
```svg
|
|
34
|
+
<g class="gateway-group">
|
|
35
|
+
<rect x="X" y="Y" width="34" height="34" fill="#fff8e1" stroke="#f9a825" stroke-width="2" transform="rotate(45, CX, CY)"/>
|
|
36
|
+
<line x1="CX-8" y1="CY-8" x2="CX+8" y2="CY+8" stroke="#e65100" stroke-width="3" stroke-linecap="round"/>
|
|
37
|
+
<line x1="CX+8" y1="CY-8" x2="CX-8" y2="CY+8" stroke="#e65100" stroke-width="3" stroke-linecap="round"/>
|
|
38
|
+
</g>
|
|
39
|
+
<text x="CX" y="CY-28" text-anchor="middle" class="gateway-label">label here</text>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### AND Gateway — bold +
|
|
43
|
+
```svg
|
|
44
|
+
<g class="gateway-group">
|
|
45
|
+
<rect x="X" y="Y" width="34" height="34" fill="#e8f5e9" stroke="#2e7d32" stroke-width="2" transform="rotate(45, CX, CY)"/>
|
|
46
|
+
<line x1="CX" y1="CY-9" x2="CX" y2="CY+9" stroke="#1b5e20" stroke-width="3" stroke-linecap="round"/>
|
|
47
|
+
<line x1="CX-9" y1="CY" x2="CX+9" y2="CY" stroke="#1b5e20" stroke-width="3" stroke-linecap="round"/>
|
|
48
|
+
</g>
|
|
49
|
+
<text x="CX" y="CY-28" text-anchor="middle" class="gateway-label">label here</text>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### OR Gateway — bold O
|
|
53
|
+
```svg
|
|
54
|
+
<g class="gateway-group">
|
|
55
|
+
<rect x="X" y="Y" width="34" height="34" fill="#e3f2fd" stroke="#1565c0" stroke-width="2" transform="rotate(45, CX, CY)"/>
|
|
56
|
+
<circle cx="CX" cy="CY" r="9" fill="none" stroke="#0d47a1" stroke-width="3"/>
|
|
57
|
+
</g>
|
|
58
|
+
<text x="CX" y="CY-28" text-anchor="middle" class="gateway-label">label here</text>
|
|
59
|
+
```
|
|
21
60
|
|
|
22
61
|
## Architecture & Layout
|
|
23
62
|
|
|
24
63
|
### Pools and Lanes
|
|
25
64
|
|
|
26
65
|
- **External participant pools**: Own pool rectangle, visually separated. Brown header, orange tasks (`#fff3e0` fill, `#e65100` stroke).
|
|
66
|
+
- **Empty external pools**: Just a labeled rectangle (header bar + empty body). No elements inside. Height: ~60px.
|
|
27
67
|
- **Organization pool**: Dark gray header, contains internal lanes. Each lane has a labeled sidebar and subtle background tint. Dashed divider lines between lanes.
|
|
28
68
|
- Pool headers: Vertical text bars on the left side.
|
|
29
69
|
|
|
30
|
-
###
|
|
70
|
+
### Message Flows with Empty Pools
|
|
31
71
|
|
|
32
|
-
|
|
72
|
+
When a message flow connects to/from an empty pool:
|
|
73
|
+
- The arrow starts/ends at the **pool border** (the rectangle edge)
|
|
74
|
+
- It does NOT connect to any element inside the pool
|
|
75
|
+
- Use dashed lines (`stroke-dasharray: 10 5`), open circle at source, filled arrow at target
|
|
33
76
|
|
|
34
77
|
### Color Scheme
|
|
35
78
|
|
|
@@ -39,6 +82,8 @@ Every BPMN element must be fully contained within a single lane or pool. Center
|
|
|
39
82
|
| Reception/admin tasks | `#e3f2fd` | `#1976d2` |
|
|
40
83
|
| Clinical/operational tasks | `#f3e5f5` | `#7b1fa2` |
|
|
41
84
|
| XOR Gateways | `#fff8e1` | `#f9a825` |
|
|
85
|
+
| AND Gateways | `#e8f5e9` | `#2e7d32` |
|
|
86
|
+
| OR Gateways | `#e3f2fd` | `#1565c0` |
|
|
42
87
|
| Start event | `#e8f5e9` | `#2e7d32` |
|
|
43
88
|
| End event | `#ffebee` | `#c62828` |
|
|
44
89
|
| Data objects | `#fff` | `#1565c0` |
|
|
@@ -47,8 +92,9 @@ Every BPMN element must be fully contained within a single lane or pool. Center
|
|
|
47
92
|
### Pool Ordering
|
|
48
93
|
|
|
49
94
|
When multiple external pools exist, minimize message flow crossing distance:
|
|
50
|
-
- Primary actor (initiates, interacts with multiple parties)
|
|
51
|
-
-
|
|
95
|
+
- Primary actor (initiates, interacts with multiple parties) near top
|
|
96
|
+
- Organization pool in the middle
|
|
97
|
+
- Supporting external participants (credit company, supplier) at bottom
|
|
52
98
|
|
|
53
99
|
### Flow Types
|
|
54
100
|
|
|
@@ -58,22 +104,44 @@ When multiple external pools exist, minimize message flow crossing distance:
|
|
|
58
104
|
- Data object: `#7986cb`
|
|
59
105
|
- Data store: `#4caf50`
|
|
60
106
|
|
|
61
|
-
##
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
107
|
+
## Interactivity
|
|
108
|
+
|
|
109
|
+
Make the diagram interactive with hover tooltips and click behavior:
|
|
110
|
+
|
|
111
|
+
### Clickable Tasks
|
|
112
|
+
Each task rectangle should show a tooltip on hover with:
|
|
113
|
+
- The task name
|
|
114
|
+
- Which pool/lane it belongs to
|
|
115
|
+
- Any data stores it reads from or writes to
|
|
116
|
+
|
|
117
|
+
### Clickable Gateways
|
|
118
|
+
Each gateway should show a tooltip on hover with:
|
|
119
|
+
- Gateway type (XOR/AND/OR)
|
|
120
|
+
- The decision question
|
|
121
|
+
- The branch conditions and where each leads
|
|
122
|
+
|
|
123
|
+
### Clickable Data Stores
|
|
124
|
+
Each data store should show a tooltip on hover with:
|
|
125
|
+
- The data store name
|
|
126
|
+
- Which tasks read from it
|
|
127
|
+
- Which tasks write to it
|
|
128
|
+
|
|
129
|
+
### Implementation
|
|
130
|
+
Use CSS hover tooltips or simple JavaScript click-to-show panels. Keep it lightweight — no external libraries. Example approach:
|
|
131
|
+
|
|
132
|
+
```html
|
|
133
|
+
<style>
|
|
134
|
+
.bpmn-tooltip { display: none; position: absolute; background: #1a1a2e; color: #fff;
|
|
135
|
+
padding: 8px 12px; border-radius: 6px; font-size: 12px; max-width: 250px;
|
|
136
|
+
z-index: 100; direction: rtl; pointer-events: none; }
|
|
137
|
+
.bpmn-element:hover .bpmn-tooltip { display: block; }
|
|
138
|
+
</style>
|
|
70
139
|
```
|
|
71
140
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
```
|
|
141
|
+
### Assumptions Panel
|
|
142
|
+
If the model includes assumptions or open questions, show a small floating info button in the top-right corner. Clicking it shows the assumptions list.
|
|
143
|
+
|
|
144
|
+
## SVG Templates
|
|
77
145
|
|
|
78
146
|
### Intermediate Events (BPMN 1.1)
|
|
79
147
|
|
|
@@ -99,39 +167,16 @@ Plain double circle, NO icon inside:
|
|
|
99
167
|
<ellipse cx="CX" cy="BOTTOM" rx="28" ry="8" class="data-store-body"/>
|
|
100
168
|
```
|
|
101
169
|
|
|
102
|
-
### Data Artifact Placement
|
|
103
|
-
|
|
104
|
-
- Data objects above or below their task, never overlapping flow lines
|
|
105
|
-
- Data stores typically below their tasks
|
|
106
|
-
- Association lines must not cross sequence flow arrows
|
|
107
|
-
|
|
108
170
|
## Arrow Routing
|
|
109
171
|
|
|
110
172
|
**Arrows must never be ambiguous.**
|
|
111
173
|
|
|
112
|
-
### Split-Merge Pattern
|
|
113
|
-
|
|
114
|
-
1. YES task above gateway center, NO task below
|
|
115
|
-
2. Merge gateway to the right of BOTH tasks
|
|
116
|
-
3. YES path: task → right → down into merge (from top)
|
|
117
|
-
4. NO path: task → right → up into merge (from bottom)
|
|
118
|
-
5. Single clean line from merge to next task
|
|
119
|
-
|
|
120
|
-
### General Rules
|
|
121
|
-
|
|
122
174
|
- Orthogonal (right-angle) routing preferred
|
|
123
175
|
- At least 30px between parallel flow lines
|
|
124
176
|
- Cross-lane flows: clear vertical drops/rises
|
|
125
177
|
- Labels (כן/לא) near the gateway, not at path end
|
|
126
178
|
- Flow labels must not overlap other elements
|
|
127
179
|
|
|
128
|
-
### Rejection/Retry Loops
|
|
129
|
-
|
|
130
|
-
- Rejection = explicit task (not just gateway output)
|
|
131
|
-
- After rejection: model the rejecting participant's next state
|
|
132
|
-
- Response to rejection = concrete task sequence
|
|
133
|
-
- Loop-back to earliest meaningful re-entry point
|
|
134
|
-
|
|
135
180
|
## Typography & Hebrew
|
|
136
181
|
|
|
137
182
|
- `Noto Sans Hebrew` from Google Fonts
|
|
@@ -145,43 +190,38 @@ Plain double circle, NO icon inside:
|
|
|
145
190
|
|
|
146
191
|
Single self-contained HTML file:
|
|
147
192
|
|
|
148
|
-
1. **Header bar**: Gradient, process title in Hebrew + English subtitle. Must say "BPMN 1.1"
|
|
149
|
-
2. **
|
|
150
|
-
3. **SVG
|
|
151
|
-
4. **
|
|
193
|
+
1. **Header bar**: Gradient, process title in Hebrew + English subtitle. Must say "BPMN 1.1". Show correct pool and lane counts.
|
|
194
|
+
2. **SVG canvas**: Full diagram in scrollable wrapper
|
|
195
|
+
3. **SVG definitions**: Drop shadow filters, arrow markers
|
|
196
|
+
4. **Interactivity**: Hover tooltips on all elements
|
|
197
|
+
5. **NO LEGEND**: Do not include a legend.
|
|
152
198
|
|
|
153
199
|
### SVG Sizing
|
|
154
200
|
|
|
155
201
|
- Width: 1700–1800px (overflow scroll)
|
|
156
|
-
- Height: ~130px per external pool, ~250px per lane, plus data artifacts
|
|
202
|
+
- Height: ~60px per empty external pool, ~130px per external pool with tasks, ~250px per lane, plus data artifacts
|
|
157
203
|
- `viewBox` matching width/height
|
|
158
204
|
|
|
159
205
|
---
|
|
160
206
|
|
|
161
|
-
#
|
|
207
|
+
# VALIDATION
|
|
162
208
|
|
|
163
|
-
**Before delivering, verify EVERY item. Fix any failure
|
|
209
|
+
**Before delivering, verify EVERY item. Fix any failure.**
|
|
164
210
|
|
|
165
|
-
## Structural Accuracy
|
|
211
|
+
## Structural Accuracy
|
|
166
212
|
- [ ] Every participant from the model appears — none omitted
|
|
167
213
|
- [ ] External participants are separate pools with message flows
|
|
168
|
-
- [ ]
|
|
169
|
-
- [ ] Every
|
|
214
|
+
- [ ] Empty pools have NO elements inside — message flows connect to pool border
|
|
215
|
+
- [ ] Every pool has complete flow (start → ... → end) — except empty external pools
|
|
216
|
+
- [ ] Every gateway has the correct type marker (bold X/+/O via SVG paths) — no text inside
|
|
170
217
|
- [ ] Every data store appears as a cylinder with data associations
|
|
171
218
|
- [ ] Every message flow appears as dashed line between pools
|
|
219
|
+
- [ ] Header pool/lane count matches actual diagram
|
|
172
220
|
|
|
173
|
-
##
|
|
174
|
-
- [ ]
|
|
175
|
-
- [ ]
|
|
176
|
-
- [ ]
|
|
177
|
-
- [ ] Data objects (folded document) and data stores (cylinder) are visually distinct
|
|
178
|
-
|
|
179
|
-
## Visual Quality
|
|
180
|
-
- [ ] No arrow paths overlap or cross ambiguously
|
|
181
|
-
- [ ] Flow labels clearly positioned near their gateway
|
|
182
|
-
- [ ] Legend includes every symbol type used
|
|
183
|
-
- [ ] Data artifacts don't overlap sequence flow paths
|
|
184
|
-
- [ ] Pool ordering minimizes message flow crossing distance
|
|
221
|
+
## Interactivity
|
|
222
|
+
- [ ] Tasks show tooltips on hover
|
|
223
|
+
- [ ] Gateways show tooltips with decision question and branches
|
|
224
|
+
- [ ] Data stores show tooltips with connected tasks
|
|
185
225
|
|
|
186
226
|
## Hebrew Language
|
|
187
|
-
- [ ] Male grammatical form used for all roles
|
|
227
|
+
- [ ] Male grammatical form used for all roles
|