drawio-mcp-server 1.7.0 → 1.8.0

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.
@@ -0,0 +1,1825 @@
1
+ "use strict";
2
+ var DrawMcp = (() => {
3
+ // src/plugin/shape-library.ts
4
+ var shapeLibrary = {
5
+ rectangle: {
6
+ category: "general",
7
+ style: "rounded=0;whiteSpace=wrap;html=1;"
8
+ },
9
+ rounded_rectangle: {
10
+ category: "general",
11
+ style: "rounded=1;whiteSpace=wrap;html=1;"
12
+ },
13
+ text: {
14
+ category: "general",
15
+ style: "text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;"
16
+ },
17
+ ellipse: {
18
+ category: "general",
19
+ style: "ellipse;whiteSpace=wrap;html=1;"
20
+ },
21
+ square: {
22
+ category: "general",
23
+ style: "whiteSpace=wrap;html=1;aspect=fixed;"
24
+ },
25
+ circle: {
26
+ category: "general",
27
+ style: "ellipse;whiteSpace=wrap;html=1;aspect=fixed;"
28
+ },
29
+ process: {
30
+ category: "general",
31
+ style: "shape=process;whiteSpace=wrap;html=1;backgroundOutline=1;"
32
+ },
33
+ diamond: {
34
+ category: "general",
35
+ style: "rhombus;whiteSpace=wrap;html=1;"
36
+ },
37
+ parallelogram: {
38
+ category: "general",
39
+ style: "shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;"
40
+ },
41
+ hexagon: {
42
+ category: "general",
43
+ style: "shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;"
44
+ },
45
+ triangle: {
46
+ category: "general",
47
+ style: "triangle;whiteSpace=wrap;html=1;"
48
+ },
49
+ cylinder3: {
50
+ category: "general",
51
+ style: "shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;"
52
+ },
53
+ cloud: {
54
+ category: "general",
55
+ style: "ellipse;shape=cloud;whiteSpace=wrap;html=1;"
56
+ },
57
+ document: {
58
+ category: "general",
59
+ style: "shape=document;whiteSpace=wrap;html=1;boundedLbl=1;"
60
+ },
61
+ internalStorage: {
62
+ category: "general",
63
+ style: "shape=internalStorage;whiteSpace=wrap;html=1;backgroundOutline=1;"
64
+ },
65
+ cube: {
66
+ category: "general",
67
+ style: "shape=cube;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;darkOpacity=0.05;darkOpacity2=0.1;"
68
+ },
69
+ step: {
70
+ category: "general",
71
+ style: "shape=step;perimeter=stepPerimeter;whiteSpace=wrap;html=1;fixedSize=1;"
72
+ },
73
+ trapezoid: {
74
+ category: "general",
75
+ style: "shape=trapezoid;perimeter=trapezoidPerimeter;whiteSpace=wrap;html=1;fixedSize=1;"
76
+ },
77
+ tape: {
78
+ category: "general",
79
+ style: "shape=tape;whiteSpace=wrap;html=1;"
80
+ },
81
+ note: {
82
+ category: "general",
83
+ style: "shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;"
84
+ },
85
+ card: {
86
+ category: "general",
87
+ style: "shape=card;whiteSpace=wrap;html=1;"
88
+ },
89
+ callout: {
90
+ category: "general",
91
+ style: "shape=callout;whiteSpace=wrap;html=1;perimeter=calloutPerimeter;"
92
+ },
93
+ umlActor: {
94
+ category: "general",
95
+ style: "shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;"
96
+ },
97
+ xor: {
98
+ category: "general",
99
+ style: "shape=xor;whiteSpace=wrap;html=1;"
100
+ },
101
+ or: {
102
+ category: "general",
103
+ style: "shape=or;whiteSpace=wrap;html=1;"
104
+ },
105
+ dataStorage: {
106
+ category: "general",
107
+ style: "shape=dataStorage;whiteSpace=wrap;html=1;fixedSize=1;"
108
+ },
109
+ swimlane: {
110
+ category: "general",
111
+ title: "Container",
112
+ style: "swimlane;startSize=0;"
113
+ },
114
+ verticalContainer: {
115
+ category: "general",
116
+ title: "Vertical Container",
117
+ style: "swimlane;whiteSpace=wrap;html=1;"
118
+ },
119
+ horizontalContainer: {
120
+ category: "general",
121
+ title: "Horizontal Container",
122
+ style: "swimlane;horizontal=0;whiteSpace=wrap;html=1;"
123
+ },
124
+ list: {
125
+ category: "general",
126
+ title: "List",
127
+ style: "swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;"
128
+ },
129
+ listItem: {
130
+ category: "general",
131
+ title: "List Item",
132
+ style: "text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;"
133
+ },
134
+ curve: {
135
+ category: "general",
136
+ style: "curved=1;endArrow=classic;html=1;rounded=0;fontSize=12;startSize=8;endSize=8;"
137
+ },
138
+ flexArrow: {
139
+ category: "general",
140
+ title: "Bidirectional Arrow",
141
+ style: "shape=flexArrow;endArrow=classic;startArrow=classic;html=1;rounded=0;fontSize=12;startSize=8;endSize=8;curved=1;"
142
+ },
143
+ arrow: {
144
+ category: "general",
145
+ title: "Arrow",
146
+ style: "shape=flexArrow;endArrow=classic;html=1;rounded=0;fontSize=12;startSize=8;endSize=8;curved=1;"
147
+ },
148
+ dashedLine: {
149
+ category: "general",
150
+ style: "endArrow=none;dashed=1;html=1;rounded=0;fontSize=12;startSize=8;endSize=8;curved=1;"
151
+ },
152
+ dottedLine: {
153
+ category: "general",
154
+ style: "endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;rounded=0;fontSize=12;startSize=8;endSize=8;"
155
+ },
156
+ line: {
157
+ category: "general",
158
+ style: "endArrow=none;html=1;rounded=0;fontSize=12;startSize=8;endSize=8;curved=1;"
159
+ },
160
+ bidirectionalConnector: {
161
+ category: "general",
162
+ style: "endArrow=classic;startArrow=classic;html=1;rounded=0;fontSize=12;startSize=8;endSize=8;curved=1;"
163
+ },
164
+ directionalConnector: {
165
+ category: "general",
166
+ style: "endArrow=classic;html=1;rounded=0;fontSize=12;startSize=8;endSize=8;curved=1;"
167
+ },
168
+ // AWS / Analytics
169
+ "mxgraph.aws4.athena": {
170
+ category: "mxgraph.aws4.analytics",
171
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#8C4FFF;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.athena;"
172
+ },
173
+ "mxgraph.aws4.elasticsearch_service": {
174
+ category: "mxgraph.aws4.analytics",
175
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#8C4FFF;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.elasticsearch_service;"
176
+ },
177
+ "mxgraph.aws4.kinesis": {
178
+ category: "mxgraph.aws4.analytics",
179
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#8C4FFF;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.kinesis;"
180
+ },
181
+ "mxgraph.aws4.kinesis_data_analytics": {
182
+ category: "mxgraph.aws4.analytics",
183
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#8C4FFF;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.kinesis_data_analytics;"
184
+ },
185
+ "mxgraph.aws4.kinesis_data_firehose": {
186
+ category: "mxgraph.aws4.analytics",
187
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#8C4FFF;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.kinesis_data_firehose;"
188
+ },
189
+ "mxgraph.aws4.kinesis_data_streams": {
190
+ category: "mxgraph.aws4.analytics",
191
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#8C4FFF;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.kinesis_data_streams;"
192
+ },
193
+ "mxgraph.aws4.managed_service_for_apache_flink": {
194
+ category: "mxgraph.aws4.analytics",
195
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#8C4FFF;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.managed_service_for_apache_flink;"
196
+ },
197
+ "mxgraph.aws4.quicksight": {
198
+ category: "mxgraph.aws4.analytics",
199
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#8C4FFF;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.quicksight;"
200
+ },
201
+ "mxgraph.aws4.managed_streaming_for_kafka": {
202
+ category: "mxgraph.aws4.analytics",
203
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#8C4FFF;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.managed_streaming_for_kafka;"
204
+ },
205
+ "mxgraph.aws4.glue": {
206
+ category: "mxgraph.aws4.analytics",
207
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#8C4FFF;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.glue;"
208
+ },
209
+ // AWS / Compute
210
+ "mxgraph.aws4.compute": {
211
+ category: "mxgraph.aws4.compute",
212
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#ED7100;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.compute;"
213
+ },
214
+ "mxgraph.aws4.ec2": {
215
+ category: "mxgraph.aws4.compute",
216
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#ED7100;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.ec2;"
217
+ },
218
+ "mxgraph.aws4.lambda": {
219
+ category: "mxgraph.aws4.compute",
220
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#ED7100;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.lambda;"
221
+ },
222
+ // AWS / Containers
223
+ "mxgraph.aws4.containers": {
224
+ category: "mxgraph.aws4.containers",
225
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#ED7100;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.containers;"
226
+ },
227
+ "mxgraph.aws4.eks": {
228
+ category: "mxgraph.aws4.containers",
229
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#ED7100;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.eks;"
230
+ },
231
+ "mxgraph.aws4.ecr": {
232
+ category: "mxgraph.aws4.containers",
233
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#ED7100;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.ecr;"
234
+ },
235
+ "mxgraph.aws4.ecs": {
236
+ category: "mxgraph.aws4.containers",
237
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#ED7100;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.ecs;"
238
+ },
239
+ "mxgraph.aws4.fargate": {
240
+ category: "mxgraph.aws4.containers",
241
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#ED7100;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.fargate;"
242
+ },
243
+ // AWS / Network & Content Delivery
244
+ "mxgraph.aws4.api_gateway": {
245
+ category: "mxgraph.aws4.network",
246
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#8C4FFF;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.api_gateway;"
247
+ },
248
+ "mxgraph.aws4.cloudfront": {
249
+ category: "mxgraph.aws4.network",
250
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#8C4FFF;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.cloudfront;"
251
+ },
252
+ "mxgraph.aws4.route_53": {
253
+ category: "mxgraph.aws4.network",
254
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#8C4FFF;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.route_53;"
255
+ },
256
+ "mxgraph.aws4.vpc_privatelink": {
257
+ category: "mxgraph.aws4.network",
258
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#8C4FFF;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.vpc_privatelink;"
259
+ },
260
+ "mxgraph.aws4.vpc": {
261
+ category: "mxgraph.aws4.network",
262
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#8C4FFF;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.vpc;"
263
+ },
264
+ "mxgraph.aws4.elastic_load_balancing": {
265
+ category: "mxgraph.aws4.network",
266
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#8C4FFF;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.elastic_load_balancing;"
267
+ },
268
+ "mxgraph.aws4.endpoint": {
269
+ category: "mxgraph.aws4.network",
270
+ style: "sketch=0;outlineConnect=0;fontColor=#232F3E;gradientColor=none;fillColor=#8C4FFF;strokeColor=none;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;pointerEvents=1;shape=mxgraph.aws4.endpoint;"
271
+ },
272
+ "mxgraph.aws4.customer_gateway": {
273
+ category: "mxgraph.aws4.network",
274
+ style: "sketch=0;outlineConnect=0;fontColor=#232F3E;gradientColor=none;fillColor=#8C4FFF;strokeColor=none;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;pointerEvents=1;shape=mxgraph.aws4.customer_gateway;"
275
+ },
276
+ "mxgraph.aws4.application_load_balancer": {
277
+ category: "mxgraph.aws4.network",
278
+ style: "sketch=0;outlineConnect=0;fontColor=#232F3E;gradientColor=none;fillColor=#8C4FFF;strokeColor=none;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;pointerEvents=1;shape=mxgraph.aws4.application_load_balancer;"
279
+ },
280
+ "mxgraph.aws4.network_load_balancer": {
281
+ category: "mxgraph.aws4.network",
282
+ style: "sketch=0;outlineConnect=0;fontColor=#232F3E;gradientColor=none;fillColor=#8C4FFF;strokeColor=none;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;pointerEvents=1;shape=mxgraph.aws4.network_load_balancer;"
283
+ },
284
+ // AWS / Application Integration
285
+ "mxgraph.aws4.sns": {
286
+ category: "mxgraph.aws4.application_integration",
287
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#E7157B;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.sns;"
288
+ },
289
+ "mxgraph.aws4.sqs": {
290
+ category: "mxgraph.aws4.application_integration",
291
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#E7157B;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.sqs;"
292
+ },
293
+ "mxgraph.aws4.eventbridge": {
294
+ category: "mxgraph.aws4.application_integration",
295
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#E7157B;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.eventbridge;"
296
+ },
297
+ "mxgraph.aws4.managed_workflows_for_apache_airflow": {
298
+ category: "mxgraph.aws4.application_integration",
299
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#E7157B;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.managed_workflows_for_apache_airflow;"
300
+ },
301
+ // AWS / Database
302
+ "mxgraph.aws4.database": {
303
+ category: "mxgraph.aws4.database",
304
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#C925D1;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.database;"
305
+ },
306
+ "mxgraph.aws4.aurora": {
307
+ category: "mxgraph.aws4.database",
308
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#C925D1;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.aurora;"
309
+ },
310
+ "mxgraph.aws4.documentdb_with_mongodb_compatibility": {
311
+ category: "mxgraph.aws4.database",
312
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#C925D1;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.documentdb_with_mongodb_compatibility;"
313
+ },
314
+ "mxgraph.aws4.dynamodb": {
315
+ category: "mxgraph.aws4.database",
316
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#C925D1;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.dynamodb;"
317
+ },
318
+ "mxgraph.aws4.elasticache": {
319
+ category: "mxgraph.aws4.database",
320
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#C925D1;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.elasticache;"
321
+ },
322
+ "mxgraph.aws4.neptune": {
323
+ category: "mxgraph.aws4.database",
324
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#C925D1;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.neptune;"
325
+ },
326
+ "mxgraph.aws4.rds": {
327
+ category: "mxgraph.aws4.database",
328
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#C925D1;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.rds;"
329
+ },
330
+ "mxgraph.aws4.redshift": {
331
+ category: "mxgraph.aws4.database",
332
+ style: "sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#C925D1;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.redshift;"
333
+ },
334
+ "mxgraph.aws4.": {
335
+ category: "mxgraph.aws4.database",
336
+ style: ""
337
+ }
338
+ };
339
+
340
+ // src/plugin/websocketManager.ts
341
+ function createWebSocketManager(options) {
342
+ let socket = null;
343
+ let reconnectAttempts = 0;
344
+ let currentState = "disconnected";
345
+ let messageHandler = null;
346
+ let pingIntervalId = null;
347
+ let reconnectTimeoutId = null;
348
+ const {
349
+ url,
350
+ maxReconnectAttempts = 5,
351
+ reconnectDelay = 3e3,
352
+ pingInterval = 3e4
353
+ } = options;
354
+ const updateState = (newState) => {
355
+ if (currentState !== newState) {
356
+ console.debug(
357
+ `[websocketManager] State change: ${currentState} \u2192 ${newState}`
358
+ );
359
+ currentState = newState;
360
+ }
361
+ };
362
+ const connect = () => {
363
+ if (socket && socket.readyState === WebSocket.OPEN) {
364
+ console.debug("[websocketManager] Already connected");
365
+ return;
366
+ }
367
+ updateState("connecting");
368
+ try {
369
+ socket = new WebSocket(url);
370
+ socket.addEventListener("open", () => {
371
+ console.debug("[websocketManager] WebSocket connection established");
372
+ reconnectAttempts = 0;
373
+ updateState("connected");
374
+ startPing();
375
+ });
376
+ socket.addEventListener("message", (event) => {
377
+ try {
378
+ const parsedMessage = JSON.parse(event.data);
379
+ console.debug("[websocketManager] Received message:", parsedMessage);
380
+ if (messageHandler) {
381
+ messageHandler(parsedMessage);
382
+ }
383
+ } catch (error) {
384
+ console.error(
385
+ "[websocketManager] Failed to parse WebSocket message:",
386
+ error
387
+ );
388
+ }
389
+ });
390
+ socket.addEventListener("close", () => {
391
+ console.debug("[websocketManager] WebSocket connection closed");
392
+ updateState("disconnected");
393
+ stopPing();
394
+ attemptReconnect();
395
+ });
396
+ socket.addEventListener("error", (event) => {
397
+ console.error("[websocketManager] WebSocket error:", event);
398
+ updateState("disconnected");
399
+ });
400
+ } catch (error) {
401
+ console.error(
402
+ "[websocketManager] Failed to create WebSocket connection:",
403
+ error
404
+ );
405
+ updateState("disconnected");
406
+ }
407
+ };
408
+ const disconnect = () => {
409
+ if (reconnectTimeoutId) {
410
+ clearTimeout(reconnectTimeoutId);
411
+ reconnectTimeoutId = null;
412
+ }
413
+ stopPing();
414
+ reconnectAttempts = 0;
415
+ if (socket) {
416
+ console.debug("[websocketManager] Closing WebSocket connection");
417
+ socket.close();
418
+ socket = null;
419
+ }
420
+ updateState("disconnected");
421
+ };
422
+ const send = (message) => {
423
+ if (!socket || socket.readyState !== WebSocket.OPEN) {
424
+ console.warn(
425
+ "[websocketManager] Cannot send message: WebSocket not connected"
426
+ );
427
+ return;
428
+ }
429
+ try {
430
+ const serialized = JSON.stringify(message);
431
+ console.debug("[websocketManager] Sending message:", message);
432
+ socket.send(serialized);
433
+ } catch (error) {
434
+ console.error("[websocketManager] Failed to send message:", error);
435
+ }
436
+ };
437
+ const getState = () => currentState;
438
+ const onMessage = (handler) => {
439
+ messageHandler = handler;
440
+ };
441
+ const attemptReconnect = () => {
442
+ if (reconnectAttempts >= maxReconnectAttempts) {
443
+ console.error(
444
+ "[websocketManager] Max reconnection attempts reached. Giving up."
445
+ );
446
+ return;
447
+ }
448
+ reconnectAttempts++;
449
+ const delay = reconnectDelay * Math.pow(1.5, reconnectAttempts - 1);
450
+ console.log(
451
+ `[websocketManager] Attempting to reconnect in ${Math.round(delay / 1e3)} seconds... (attempt ${reconnectAttempts}/${maxReconnectAttempts})`
452
+ );
453
+ reconnectTimeoutId = window.setTimeout(() => {
454
+ reconnectTimeoutId = null;
455
+ connect();
456
+ }, delay);
457
+ };
458
+ const startPing = () => {
459
+ stopPing();
460
+ pingIntervalId = window.setInterval(() => {
461
+ if (getState() === "connected") {
462
+ send({ type: "PING" });
463
+ }
464
+ }, pingInterval);
465
+ };
466
+ const stopPing = () => {
467
+ if (pingIntervalId !== null) {
468
+ clearInterval(pingIntervalId);
469
+ pingIntervalId = null;
470
+ }
471
+ };
472
+ const ping = () => {
473
+ return new Promise((resolve) => {
474
+ if (getState() !== "connected") {
475
+ resolve(false);
476
+ return;
477
+ }
478
+ const timeoutId = setTimeout(() => {
479
+ resolve(false);
480
+ }, 5e3);
481
+ send({ type: "PING", message: "Ping from plugin" });
482
+ setTimeout(() => {
483
+ clearTimeout(timeoutId);
484
+ resolve(getState() === "connected");
485
+ }, 1e3);
486
+ });
487
+ };
488
+ return {
489
+ connect,
490
+ disconnect,
491
+ send,
492
+ getState,
493
+ onMessage,
494
+ ping
495
+ };
496
+ }
497
+
498
+ // src/plugin/pluginConfig.ts
499
+ var DEFAULT_PLUGIN_CONFIG = {
500
+ websocketPort: 3333,
501
+ serverUrl: ""
502
+ };
503
+ var PLUGIN_CONFIG_KEY = "drawio-mcp-plugin-config";
504
+ var cachedConfig = null;
505
+ async function fetchPluginConfig() {
506
+ if (cachedConfig) {
507
+ return cachedConfig;
508
+ }
509
+ try {
510
+ const response = await fetch("/api/config");
511
+ if (response.ok) {
512
+ const serverConfig = await response.json();
513
+ cachedConfig = {
514
+ websocketPort: serverConfig.websocketPort || DEFAULT_PLUGIN_CONFIG.websocketPort,
515
+ serverUrl: serverConfig.serverUrl || window.location.origin
516
+ };
517
+ writePluginConfig(cachedConfig);
518
+ return cachedConfig;
519
+ }
520
+ } catch (error) {
521
+ console.warn("[pluginConfig] Failed to fetch config from server:", error);
522
+ }
523
+ return readPluginConfig();
524
+ }
525
+ function readPluginConfig() {
526
+ try {
527
+ const stored = localStorage.getItem(PLUGIN_CONFIG_KEY);
528
+ if (stored) {
529
+ const parsed = JSON.parse(stored);
530
+ const validated = validatePluginConfig(parsed);
531
+ if (validated.isValid && validated.config) {
532
+ return validated.config;
533
+ }
534
+ }
535
+ } catch (error) {
536
+ console.warn("[pluginConfig] Failed to read from localStorage:", error);
537
+ }
538
+ return { ...DEFAULT_PLUGIN_CONFIG };
539
+ }
540
+ function writePluginConfig(config) {
541
+ try {
542
+ localStorage.setItem(PLUGIN_CONFIG_KEY, JSON.stringify(config));
543
+ cachedConfig = config;
544
+ } catch (error) {
545
+ console.error("[pluginConfig] Failed to write to localStorage:", error);
546
+ throw error;
547
+ }
548
+ }
549
+ function validatePluginConfig(config) {
550
+ if (!config || typeof config !== "object") {
551
+ return { isValid: false, error: "Configuration must be an object" };
552
+ }
553
+ const cfg = config;
554
+ if (typeof cfg.websocketPort !== "number") {
555
+ return { isValid: false, error: "websocketPort must be a number" };
556
+ }
557
+ if (cfg.websocketPort < 1024 || cfg.websocketPort > 65535) {
558
+ return {
559
+ isValid: false,
560
+ error: "websocketPort must be between 1024 and 65535"
561
+ };
562
+ }
563
+ return {
564
+ isValid: true,
565
+ config: {
566
+ websocketPort: cfg.websocketPort,
567
+ serverUrl: cfg.serverUrl || ""
568
+ }
569
+ };
570
+ }
571
+ function buildWebSocketUrl(config) {
572
+ const host = window.location.hostname;
573
+ return `ws://${host}:${config.websocketPort}`;
574
+ }
575
+
576
+ // src/plugin/settingsDialog.ts
577
+ function createDialogContainer() {
578
+ const container = document.createElement("div");
579
+ container.id = "mcp-settings-dialog";
580
+ container.style.cssText = `
581
+ position: fixed;
582
+ top: 0;
583
+ left: 0;
584
+ width: 100%;
585
+ height: 100%;
586
+ background-color: rgba(0, 0, 0, 0.5);
587
+ display: flex;
588
+ justify-content: center;
589
+ align-items: center;
590
+ z-index: 10000;
591
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
592
+ `;
593
+ container.addEventListener("click", (e) => {
594
+ if (e.target === container) {
595
+ e.stopPropagation();
596
+ }
597
+ });
598
+ return container;
599
+ }
600
+ function createDialogContent() {
601
+ const content = document.createElement("div");
602
+ content.className = "dialog-content";
603
+ content.style.cssText = `
604
+ background: white;
605
+ border-radius: 8px;
606
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
607
+ max-width: 500px;
608
+ width: 90%;
609
+ max-height: 90vh;
610
+ overflow-y: auto;
611
+ position: relative;
612
+ `;
613
+ return content;
614
+ }
615
+ function createDialogHeader(title, onClose) {
616
+ const header = document.createElement("div");
617
+ header.className = "dialog-header";
618
+ header.style.cssText = `
619
+ padding: 16px 20px;
620
+ border-bottom: 1px solid #e0e0e0;
621
+ display: flex;
622
+ justify-content: space-between;
623
+ align-items: center;
624
+ `;
625
+ const titleEl = document.createElement("h2");
626
+ titleEl.textContent = title;
627
+ titleEl.style.cssText = `
628
+ margin: 0;
629
+ font-size: 18px;
630
+ font-weight: 600;
631
+ color: #333;
632
+ `;
633
+ const closeBtn = document.createElement("button");
634
+ closeBtn.textContent = "\xD7";
635
+ closeBtn.style.cssText = `
636
+ background: none;
637
+ border: none;
638
+ font-size: 24px;
639
+ cursor: pointer;
640
+ padding: 0;
641
+ width: 24px;
642
+ height: 24px;
643
+ display: flex;
644
+ align-items: center;
645
+ justify-content: center;
646
+ color: #666;
647
+ border-radius: 4px;
648
+ `;
649
+ closeBtn.title = "Close";
650
+ closeBtn.addEventListener("mouseenter", () => {
651
+ closeBtn.style.backgroundColor = "#f5f5f5";
652
+ });
653
+ closeBtn.addEventListener("mouseleave", () => {
654
+ closeBtn.style.backgroundColor = "transparent";
655
+ });
656
+ closeBtn.addEventListener("click", onClose);
657
+ header.appendChild(titleEl);
658
+ header.appendChild(closeBtn);
659
+ return header;
660
+ }
661
+ function createDialogBody(state, actions) {
662
+ const body = document.createElement("div");
663
+ body.className = "dialog-body";
664
+ body.style.cssText = `
665
+ padding: 20px;
666
+ `;
667
+ const statusSection = createStatusSection(state);
668
+ body.appendChild(statusSection);
669
+ const formSection = createFormSection(state, actions);
670
+ body.appendChild(formSection);
671
+ return body;
672
+ }
673
+ function createStatusSection(state) {
674
+ const section = document.createElement("div");
675
+ section.className = "status-section";
676
+ section.style.cssText = `
677
+ margin-bottom: 24px;
678
+ padding: 16px;
679
+ background: #f8f9fa;
680
+ border-radius: 6px;
681
+ border: 1px solid #e9ecef;
682
+ `;
683
+ const title = document.createElement("div");
684
+ title.style.cssText = `
685
+ font-weight: 600;
686
+ margin-bottom: 8px;
687
+ color: #333;
688
+ `;
689
+ title.textContent = "Connection Status";
690
+ const statusIndicator = document.createElement("div");
691
+ statusIndicator.className = "status-indicator";
692
+ statusIndicator.style.cssText = `
693
+ display: flex;
694
+ align-items: center;
695
+ gap: 8px;
696
+ margin-bottom: 4px;
697
+ `;
698
+ const indicator = document.createElement("div");
699
+ indicator.style.cssText = `
700
+ width: 12px;
701
+ height: 12px;
702
+ border-radius: 50%;
703
+ flex-shrink: 0;
704
+ `;
705
+ switch (state.connectionState) {
706
+ case "connected":
707
+ indicator.style.backgroundColor = "#28a745";
708
+ break;
709
+ case "connecting":
710
+ indicator.style.backgroundColor = "#ffc107";
711
+ break;
712
+ case "disconnected":
713
+ indicator.style.backgroundColor = "#dc3545";
714
+ break;
715
+ }
716
+ const statusText = document.createElement("span");
717
+ statusText.textContent = state.connectionState.charAt(0).toUpperCase() + state.connectionState.slice(1);
718
+ statusText.style.fontWeight = "500";
719
+ statusIndicator.appendChild(indicator);
720
+ statusIndicator.appendChild(statusText);
721
+ const portDisplay = document.createElement("div");
722
+ portDisplay.style.cssText = `
723
+ font-size: 14px;
724
+ color: #666;
725
+ `;
726
+ portDisplay.textContent = `Port: ${state.config.websocketPort}`;
727
+ section.appendChild(title);
728
+ section.appendChild(statusIndicator);
729
+ section.appendChild(portDisplay);
730
+ return section;
731
+ }
732
+ function createFormSection(state, actions) {
733
+ const section = document.createElement("div");
734
+ section.className = "form-section";
735
+ const portGroup = document.createElement("div");
736
+ portGroup.className = "form-group";
737
+ portGroup.style.cssText = `
738
+ margin-bottom: 16px;
739
+ `;
740
+ const label = document.createElement("label");
741
+ label.textContent = "WebSocket Port";
742
+ label.htmlFor = "mcp-port-input";
743
+ label.style.cssText = `
744
+ display: block;
745
+ margin-bottom: 6px;
746
+ font-weight: 500;
747
+ color: #333;
748
+ `;
749
+ const input = document.createElement("input");
750
+ input.id = "mcp-port-input";
751
+ input.type = "number";
752
+ input.min = "1024";
753
+ input.max = "65535";
754
+ input.value = state.formData.port;
755
+ input.style.cssText = `
756
+ width: 100%;
757
+ padding: 8px 12px;
758
+ border: 1px solid #ddd;
759
+ border-radius: 4px;
760
+ font-size: 14px;
761
+ box-sizing: border-box;
762
+ `;
763
+ if (state.errors.port) {
764
+ input.style.borderColor = "#dc3545";
765
+ }
766
+ input.addEventListener("input", (e) => {
767
+ const value = e.target.value;
768
+ window.dispatchEvent(
769
+ new CustomEvent("mcp-settings-message", {
770
+ detail: { type: "UPDATE_PORT", port: value }
771
+ })
772
+ );
773
+ });
774
+ const hint = document.createElement("div");
775
+ hint.textContent = "Port must be between 1024 and 65535";
776
+ hint.style.cssText = `
777
+ font-size: 12px;
778
+ color: #666;
779
+ margin-top: 4px;
780
+ `;
781
+ if (state.errors.port) {
782
+ const error = document.createElement("div");
783
+ error.textContent = state.errors.port;
784
+ error.style.cssText = `
785
+ font-size: 12px;
786
+ color: #dc3545;
787
+ margin-top: 4px;
788
+ `;
789
+ portGroup.appendChild(error);
790
+ }
791
+ portGroup.appendChild(label);
792
+ portGroup.appendChild(input);
793
+ portGroup.appendChild(hint);
794
+ section.appendChild(portGroup);
795
+ return section;
796
+ }
797
+ function createDialogFooter(state, actions) {
798
+ const footer = document.createElement("div");
799
+ footer.className = "dialog-footer";
800
+ footer.style.cssText = `
801
+ padding: 16px 20px;
802
+ border-top: 1px solid #e0e0e0;
803
+ display: flex;
804
+ justify-content: space-between;
805
+ gap: 12px;
806
+ flex-wrap: wrap;
807
+ `;
808
+ const leftActions = document.createElement("div");
809
+ leftActions.style.cssText = `
810
+ display: flex;
811
+ gap: 8px;
812
+ flex-wrap: wrap;
813
+ `;
814
+ const rightActions = document.createElement("div");
815
+ rightActions.style.cssText = `
816
+ display: flex;
817
+ gap: 8px;
818
+ `;
819
+ const cancelBtn = createButton("Cancel", "ghost", () => {
820
+ window.dispatchEvent(
821
+ new CustomEvent("mcp-settings-message", {
822
+ detail: { type: "CLOSE" }
823
+ })
824
+ );
825
+ });
826
+ const saveBtn = createButton(
827
+ state.isSaving ? "Saving..." : "Save",
828
+ "primary",
829
+ () => {
830
+ window.dispatchEvent(
831
+ new CustomEvent("mcp-settings-message", {
832
+ detail: { type: "SAVE" }
833
+ })
834
+ );
835
+ },
836
+ state.isSaving
837
+ );
838
+ rightActions.appendChild(cancelBtn);
839
+ rightActions.appendChild(saveBtn);
840
+ footer.appendChild(leftActions);
841
+ footer.appendChild(rightActions);
842
+ return footer;
843
+ }
844
+ function createButton(text, variant, onClick, disabled = false) {
845
+ const btn = document.createElement("button");
846
+ btn.textContent = text;
847
+ btn.disabled = disabled;
848
+ btn.style.cssText = `
849
+ padding: 8px 16px;
850
+ border-radius: 4px;
851
+ font-size: 14px;
852
+ cursor: pointer;
853
+ border: 1px solid transparent;
854
+ transition: all 0.2s;
855
+ `;
856
+ switch (variant) {
857
+ case "primary":
858
+ btn.style.cssText += `
859
+ background-color: #007bff;
860
+ color: white;
861
+ border-color: #007bff;
862
+ `;
863
+ btn.addEventListener("mouseenter", () => {
864
+ if (!disabled) btn.style.backgroundColor = "#0056b3";
865
+ });
866
+ btn.addEventListener("mouseleave", () => {
867
+ if (!disabled) btn.style.backgroundColor = "#007bff";
868
+ });
869
+ break;
870
+ case "secondary":
871
+ btn.style.cssText += `
872
+ background-color: #6c757d;
873
+ color: white;
874
+ border-color: #6c757d;
875
+ `;
876
+ btn.addEventListener("mouseenter", () => {
877
+ if (!disabled) btn.style.backgroundColor = "#545b62";
878
+ });
879
+ btn.addEventListener("mouseleave", () => {
880
+ if (!disabled) btn.style.backgroundColor = "#6c757d";
881
+ });
882
+ break;
883
+ case "ghost":
884
+ btn.style.cssText += `
885
+ background-color: transparent;
886
+ color: #6c757d;
887
+ border-color: #6c757d;
888
+ `;
889
+ btn.addEventListener("mouseenter", () => {
890
+ if (!disabled) {
891
+ btn.style.backgroundColor = "#f8f9fa";
892
+ }
893
+ });
894
+ btn.addEventListener("mouseleave", () => {
895
+ if (!disabled) btn.style.backgroundColor = "transparent";
896
+ });
897
+ break;
898
+ }
899
+ if (disabled) {
900
+ btn.style.cssText += `
901
+ opacity: 0.6;
902
+ cursor: not-allowed;
903
+ `;
904
+ }
905
+ btn.addEventListener("click", onClick);
906
+ return btn;
907
+ }
908
+ function createSettingsDialog(initialState, actions) {
909
+ let currentState = { ...initialState };
910
+ let dialogElement = null;
911
+ let isVisible = false;
912
+ const update = (newState) => {
913
+ currentState = { ...newState };
914
+ if (dialogElement && isVisible) {
915
+ render();
916
+ }
917
+ };
918
+ const render = () => {
919
+ if (dialogElement && dialogElement.parentNode) {
920
+ dialogElement.parentNode.removeChild(dialogElement);
921
+ }
922
+ const container = createDialogContainer();
923
+ const content = createDialogContent();
924
+ const header = createDialogHeader("MCP Settings", () => actions.onClose());
925
+ const body = createDialogBody(currentState, actions);
926
+ const footer = createDialogFooter(currentState, actions);
927
+ content.appendChild(header);
928
+ content.appendChild(body);
929
+ content.appendChild(footer);
930
+ container.appendChild(content);
931
+ dialogElement = container;
932
+ isVisible = true;
933
+ setupMessageListeners(container, actions);
934
+ return container;
935
+ };
936
+ const setupMessageListeners = (container, actions2) => {
937
+ const handleMessage = (event) => {
938
+ const message = event.detail;
939
+ switch (message.type) {
940
+ case "UPDATE_PORT":
941
+ currentState.formData.port = message.port;
942
+ delete currentState.errors.port;
943
+ break;
944
+ case "SAVE":
945
+ if (!validateAndSave()) {
946
+ update(currentState);
947
+ }
948
+ break;
949
+ case "CLOSE":
950
+ actions2.onClose();
951
+ break;
952
+ }
953
+ };
954
+ window.addEventListener(
955
+ "mcp-settings-message",
956
+ handleMessage
957
+ );
958
+ const observer = new MutationObserver((mutations) => {
959
+ mutations.forEach((mutation) => {
960
+ mutation.removedNodes.forEach((node) => {
961
+ if (node === container) {
962
+ window.removeEventListener(
963
+ "mcp-settings-message",
964
+ handleMessage
965
+ );
966
+ observer.disconnect();
967
+ }
968
+ });
969
+ });
970
+ });
971
+ if (container.parentNode) {
972
+ observer.observe(container.parentNode, { childList: true });
973
+ }
974
+ };
975
+ const validateAndSave = () => {
976
+ const portNum = parseInt(currentState.formData.port, 10);
977
+ if (isNaN(portNum)) {
978
+ currentState.errors.port = "Port must be a number";
979
+ return false;
980
+ }
981
+ if (portNum < 1024 || portNum > 65535) {
982
+ currentState.errors.port = "Port must be between 1024 and 65535";
983
+ return false;
984
+ }
985
+ currentState.errors = {};
986
+ currentState.isSaving = true;
987
+ const newConfig = {
988
+ websocketPort: portNum,
989
+ serverUrl: currentState.config.serverUrl
990
+ };
991
+ actions.onSave(newConfig);
992
+ return true;
993
+ };
994
+ const dialogProxy = {
995
+ get element() {
996
+ if (!dialogElement) {
997
+ render();
998
+ }
999
+ return dialogElement;
1000
+ },
1001
+ update
1002
+ };
1003
+ return dialogProxy;
1004
+ }
1005
+ function showSettingsDialog(dialog) {
1006
+ if (!dialog.element.parentNode) {
1007
+ document.body.appendChild(dialog.element);
1008
+ }
1009
+ }
1010
+ function hideSettingsDialog(dialog) {
1011
+ if (dialog.element.parentNode) {
1012
+ dialog.element.parentNode.removeChild(dialog.element);
1013
+ }
1014
+ }
1015
+
1016
+ // src/plugin/drawio-tools.ts
1017
+ function transform_NamedNodeMap_to_record(attributes) {
1018
+ const tstr = Object.prototype.toString.call(attributes);
1019
+ if (tstr !== "[object NamedNodeMap]") {
1020
+ return attributes;
1021
+ }
1022
+ if (attributes.length === void 0) {
1023
+ return attributes;
1024
+ }
1025
+ let transformed_attributes = {};
1026
+ for (let i = 0; i < attributes.length; i++) {
1027
+ const attr = attributes[i];
1028
+ if (attr && attr.name && attr.value !== void 0) {
1029
+ transformed_attributes[attr.name] = attr.value;
1030
+ }
1031
+ }
1032
+ return transformed_attributes;
1033
+ }
1034
+ function transform_cells_NamedNodeMap_to_attributes(cell) {
1035
+ if (cell.value.attributes && typeof cell.value.attributes === "object") {
1036
+ const attributes = cell.value.attributes;
1037
+ return transform_NamedNodeMap_to_record(attributes);
1038
+ }
1039
+ return {};
1040
+ }
1041
+ function remove_circular_dependencies(obj, visited = /* @__PURE__ */ new WeakSet(), path = []) {
1042
+ if (obj === null || typeof obj !== "object") {
1043
+ return obj;
1044
+ }
1045
+ if (Array.isArray(obj)) {
1046
+ if (visited.has(obj)) {
1047
+ return `[Circular ${path.join(".")}]`;
1048
+ }
1049
+ visited.add(obj);
1050
+ return obj.map(
1051
+ (item, index) => remove_circular_dependencies(item, visited, [...path, `[${index}]`])
1052
+ );
1053
+ }
1054
+ const tstr = Object.prototype.toString.call(obj);
1055
+ if (tstr === "[object NamedNodeMap]") {
1056
+ return transform_NamedNodeMap_to_record(obj);
1057
+ }
1058
+ if (tstr !== "[object Object]" && tstr !== "[object Element]") {
1059
+ return obj;
1060
+ }
1061
+ if (visited.has(obj)) {
1062
+ return `[Circular ${path.join(".")}]`;
1063
+ }
1064
+ visited.add(obj);
1065
+ const result = {};
1066
+ for (const key in obj) {
1067
+ const value = obj[key];
1068
+ if (typeof value !== "function" && key !== "children" && key !== "edges" && !key.startsWith("aria") && key !== "ownerDocument" && key !== "part" && key !== "classList" && key !== "childNodes" && key !== "shadowRoot" && key !== "innerHTML" && key !== "outerHTML" && key !== "scrollTop" && key !== "scrollLeft" && key !== "scrollWidth" && key !== "scrollHeight" && key !== "clientTop" && key !== "clientLeft" && key !== "clientWidth" && key !== "clientHeight" && key !== "onbeforecopy" && key !== "onbeforecut" && key !== "onbeforepaste" && key !== "onsearch" && key !== "elementTiming" && key !== "onfullscreenchange" && key !== "onfullscreenerror" && key !== "onwebkitfullscreenchange" && key !== "onwebkitfullscreenerror" && key !== "firstElementChild" && key !== "lastElementChild" && key !== "childElementCount" && key !== "previousElementSibling" && key !== "nextElementSibling" && key !== "currentCSSZoom" && key !== "parentNode" && key !== "parentElement" && key !== "firstChild" && key !== "lastChild" && key !== "previousSibling" && key !== "nextSibling" && key !== "nodeValue" && key !== "textContent") {
1069
+ let stripped_value = {};
1070
+ if ((key === "parent" || key === "source" || key === "target") && value !== void 0 && value !== null) {
1071
+ stripped_value = {
1072
+ id: value.id
1073
+ };
1074
+ } else {
1075
+ stripped_value = value;
1076
+ }
1077
+ result[key] = remove_circular_dependencies(stripped_value, visited, [
1078
+ ...path,
1079
+ key
1080
+ ]);
1081
+ }
1082
+ }
1083
+ return result;
1084
+ }
1085
+ function add_new_rectangle(ui2, options) {
1086
+ const { editor } = ui2;
1087
+ const { graph } = editor;
1088
+ const x = options.x || 100;
1089
+ const y = options.y || 100;
1090
+ const width = options.width || 120;
1091
+ const height = options.height || 60;
1092
+ const text = options.text || "";
1093
+ const style = options.style || "whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;";
1094
+ graph.getModel().beginUpdate();
1095
+ try {
1096
+ const vertex = graph.insertVertex(
1097
+ graph.getDefaultParent(),
1098
+ null,
1099
+ text,
1100
+ x,
1101
+ y,
1102
+ width,
1103
+ height,
1104
+ style
1105
+ );
1106
+ return vertex;
1107
+ } finally {
1108
+ graph.getModel().endUpdate();
1109
+ }
1110
+ }
1111
+ function delete_cell_by_id(ui2, options) {
1112
+ const { editor } = ui2;
1113
+ const { graph } = editor;
1114
+ const cell_id = options.cell_id;
1115
+ const cell = graph.getModel().getCell(cell_id);
1116
+ if (!cell) {
1117
+ return false;
1118
+ }
1119
+ graph.getModel().beginUpdate();
1120
+ try {
1121
+ graph.removeCells([cell]);
1122
+ return true;
1123
+ } finally {
1124
+ graph.getModel().endUpdate();
1125
+ }
1126
+ }
1127
+ function add_edge(ui2, options) {
1128
+ const { editor } = ui2;
1129
+ const { graph } = editor;
1130
+ const model = graph.getModel();
1131
+ const source = model.getCell(options.source_id);
1132
+ const target = model.getCell(options.target_id);
1133
+ if (!source || !target) {
1134
+ return null;
1135
+ }
1136
+ const defaultStyle = "endArrow=classic;html=1;rounded=0;";
1137
+ const style = options.style || defaultStyle;
1138
+ const text = options.text || "";
1139
+ model.beginUpdate();
1140
+ try {
1141
+ const edge = graph.insertEdge(
1142
+ graph.getDefaultParent(),
1143
+ null,
1144
+ text,
1145
+ source,
1146
+ target,
1147
+ style
1148
+ );
1149
+ return edge;
1150
+ } finally {
1151
+ model.endUpdate();
1152
+ }
1153
+ }
1154
+ function edit_cell(ui2, options) {
1155
+ const { editor } = ui2;
1156
+ const { graph } = editor;
1157
+ const model = graph.getModel();
1158
+ const cell_id = options.cell_id;
1159
+ if (!cell_id) {
1160
+ throw new Error("edit_cell requires a cell_id");
1161
+ }
1162
+ const cell = model.getCell(cell_id);
1163
+ if (!cell) {
1164
+ throw new Error(`edit_cell could not find cell with id '${cell_id}'`);
1165
+ }
1166
+ model.beginUpdate();
1167
+ try {
1168
+ const has_position_change = options.x !== void 0 || options.y !== void 0;
1169
+ const has_size_change = options.width !== void 0 || options.height !== void 0;
1170
+ if (has_position_change || has_size_change) {
1171
+ const geometry = cell.geometry ? cell.geometry.clone() : null;
1172
+ if (!geometry) {
1173
+ throw new Error(
1174
+ `Cell '${cell_id}' does not support geometry updates (missing geometry)`
1175
+ );
1176
+ }
1177
+ if (options.x !== void 0) geometry.x = options.x;
1178
+ if (options.y !== void 0) geometry.y = options.y;
1179
+ if (options.width !== void 0) geometry.width = options.width;
1180
+ if (options.height !== void 0)
1181
+ geometry.height = options.height;
1182
+ model.setGeometry(cell, geometry);
1183
+ }
1184
+ if (options.text !== void 0) {
1185
+ graph.cellLabelChanged(cell, options.text, false);
1186
+ }
1187
+ if (options.style !== void 0) {
1188
+ graph.setCellStyle(options.style, [cell]);
1189
+ }
1190
+ } finally {
1191
+ model.endUpdate();
1192
+ }
1193
+ return cell;
1194
+ }
1195
+ function edit_edge(ui2, options) {
1196
+ const { editor } = ui2;
1197
+ const { graph } = editor;
1198
+ const model = graph.getModel();
1199
+ const cell_id = options.cell_id;
1200
+ if (!cell_id) {
1201
+ throw new Error("edit_edge requires a cell_id");
1202
+ }
1203
+ const edge = model.getCell(cell_id);
1204
+ if (!edge) {
1205
+ throw new Error(`edit_edge could not find edge with id '${cell_id}'`);
1206
+ }
1207
+ if (!edge.edge) {
1208
+ throw new Error(`Cell '${cell_id}' is not an edge`);
1209
+ }
1210
+ model.beginUpdate();
1211
+ try {
1212
+ if (options.source_id !== void 0) {
1213
+ const newSource = model.getCell(options.source_id);
1214
+ if (!newSource) {
1215
+ throw new Error(
1216
+ `edit_edge could not find source cell '${options.source_id}'`
1217
+ );
1218
+ }
1219
+ model.setTerminal(edge, newSource, true);
1220
+ }
1221
+ if (options.target_id !== void 0) {
1222
+ const newTarget = model.getCell(options.target_id);
1223
+ if (!newTarget) {
1224
+ throw new Error(
1225
+ `edit_edge could not find target cell '${options.target_id}'`
1226
+ );
1227
+ }
1228
+ model.setTerminal(edge, newTarget, false);
1229
+ }
1230
+ if (options.text !== void 0) {
1231
+ graph.cellLabelChanged(edge, options.text, false);
1232
+ }
1233
+ if (options.style !== void 0) {
1234
+ graph.setCellStyle(options.style, [edge]);
1235
+ }
1236
+ } finally {
1237
+ model.endUpdate();
1238
+ }
1239
+ return edge;
1240
+ }
1241
+ function set_cell_shape(ui2, options) {
1242
+ const { editor } = ui2;
1243
+ const { graph } = editor;
1244
+ const model = graph.getModel();
1245
+ const cell_id = options.cell_id;
1246
+ const shape_name = options.shape_name;
1247
+ if (!cell_id) {
1248
+ throw new Error("set_cell_shape requires a cell_id");
1249
+ }
1250
+ if (!shape_name) {
1251
+ throw new Error("set_cell_shape requires a shape_name");
1252
+ }
1253
+ const cell = model.getCell(cell_id);
1254
+ if (!cell) {
1255
+ throw new Error(`set_cell_shape could not find cell with id '${cell_id}'`);
1256
+ }
1257
+ if (cell.edge) {
1258
+ throw new Error(
1259
+ `Cell '${cell_id}' is an edge; set_cell_shape expects a vertex`
1260
+ );
1261
+ }
1262
+ const style = shapeLibrary?.[shape_name]?.style;
1263
+ if (!style) {
1264
+ throw new Error(
1265
+ `set_cell_shape could not find a shape named '${shape_name}'`
1266
+ );
1267
+ }
1268
+ model.beginUpdate();
1269
+ try {
1270
+ graph.setCellStyle(style, [cell]);
1271
+ } finally {
1272
+ model.endUpdate();
1273
+ }
1274
+ return cell;
1275
+ }
1276
+ function set_cell_data(ui2, options) {
1277
+ const { editor } = ui2;
1278
+ const { graph } = editor;
1279
+ const model = graph.getModel();
1280
+ const mxUtils = window.mxUtils;
1281
+ const cell_id = options.cell_id;
1282
+ const key = options.key;
1283
+ const value = options.value;
1284
+ if (!cell_id) {
1285
+ throw new Error("set_cell_data requires a cell_id");
1286
+ }
1287
+ if (!key) {
1288
+ throw new Error("set_cell_data requires a key");
1289
+ }
1290
+ if (value === void 0) {
1291
+ throw new Error("set_cell_data requires a value");
1292
+ }
1293
+ const cell = model.getCell(cell_id);
1294
+ if (!cell) {
1295
+ throw new Error(`set_cell_data could not find cell with id '${cell_id}'`);
1296
+ }
1297
+ model.beginUpdate();
1298
+ try {
1299
+ let d = graph.getModel().getValue(cell);
1300
+ if (!mxUtils.isNode(d)) {
1301
+ var h = mxUtils.createXmlDocument().createElement("object");
1302
+ h.setAttribute("label", d || "");
1303
+ d = h;
1304
+ }
1305
+ d = d.cloneNode(true);
1306
+ d.setAttribute(key, value);
1307
+ graph.getModel().setValue(cell, d);
1308
+ } catch (e) {
1309
+ console.error(`[set-cell-data] error`, e);
1310
+ } finally {
1311
+ model.endUpdate();
1312
+ }
1313
+ return cell;
1314
+ }
1315
+ function get_shape_categories(ui2) {
1316
+ const shapes = shapeLibrary;
1317
+ const categories = /* @__PURE__ */ new Set();
1318
+ for (const shape of Object.values(shapes)) {
1319
+ categories.add(shape.category || "General");
1320
+ }
1321
+ return [...categories];
1322
+ }
1323
+ function get_shapes_in_category(ui2, options) {
1324
+ const shapes = shapeLibrary;
1325
+ return Object.entries(shapes).filter(([_, shape]) => {
1326
+ return shape.category === options.category_id;
1327
+ }).map(([shape_key, shape_value]) => {
1328
+ return {
1329
+ id: shape_key,
1330
+ title: shape_value.title || shape_key
1331
+ };
1332
+ });
1333
+ }
1334
+ function get_shape_by_name(ui2, options) {
1335
+ const shapes = shapeLibrary;
1336
+ const shape = shapes[options.shape_name];
1337
+ if (!shape) return null;
1338
+ return {
1339
+ id: options.shape_name,
1340
+ ...shape
1341
+ };
1342
+ }
1343
+ function add_cell_of_shape(ui2, options) {
1344
+ const { editor } = ui2;
1345
+ const { graph } = editor;
1346
+ const shape_name = options.shape_name || "rectangle";
1347
+ const x = options.x || 100;
1348
+ const y = options.y || 100;
1349
+ const width = options.width || 120;
1350
+ const height = options.height || 80;
1351
+ const text = options.text || "";
1352
+ const style = options.style || "";
1353
+ const shape_entry = get_shape_by_name(ui2, { shape_name });
1354
+ if (!shape_entry) return null;
1355
+ graph.getModel().beginUpdate();
1356
+ try {
1357
+ const cell = graph.insertVertex(
1358
+ graph.getDefaultParent(),
1359
+ null,
1360
+ text,
1361
+ x,
1362
+ y,
1363
+ width,
1364
+ height,
1365
+ `${shape_entry.style};${style}`,
1366
+ false
1367
+ );
1368
+ return cell;
1369
+ } finally {
1370
+ graph.getModel().endUpdate();
1371
+ }
1372
+ }
1373
+ function list_paged_model(ui2, options = {}) {
1374
+ const { editor } = ui2;
1375
+ const { graph } = editor;
1376
+ const model = graph.getModel();
1377
+ const cells = model.cells;
1378
+ if (!cells) {
1379
+ return [];
1380
+ }
1381
+ function parse_style_attributes(style) {
1382
+ const attributes = {};
1383
+ if (!style) return attributes;
1384
+ const pairs = style.split(";");
1385
+ for (const pair of pairs) {
1386
+ const [key, ...valueParts] = pair.split("=");
1387
+ if (key && valueParts.length > 0) {
1388
+ attributes[key.trim()] = valueParts.join("=").trim();
1389
+ }
1390
+ }
1391
+ return attributes;
1392
+ }
1393
+ function extract_cell_attributes(cell) {
1394
+ const attributes = {};
1395
+ attributes.id = cell.id || "";
1396
+ attributes.edge = cell.edge || false;
1397
+ if (cell.style) {
1398
+ Object.assign(attributes, parse_style_attributes(cell.style));
1399
+ }
1400
+ if (cell.value && typeof cell.value === "object" && cell.value.attributes) {
1401
+ const transformed_attributes = transform_cells_NamedNodeMap_to_attributes(cell);
1402
+ Object.assign(attributes, transformed_attributes);
1403
+ }
1404
+ if (cell.value && typeof cell.value === "string") {
1405
+ attributes.text = cell.value;
1406
+ }
1407
+ return attributes;
1408
+ }
1409
+ function matches_cell_type(cell, cell_type) {
1410
+ switch (cell_type) {
1411
+ case "edge":
1412
+ return cell.edge === true || cell.edge === 1;
1413
+ case "vertex":
1414
+ return cell.edge === false;
1415
+ case "object":
1416
+ return cell.value?.nodeName === "object";
1417
+ case "group":
1418
+ return cell.style === "group";
1419
+ default:
1420
+ return true;
1421
+ }
1422
+ }
1423
+ let filtered_cells = Object.values(cells);
1424
+ if (options.filter) {
1425
+ const filter = options.filter;
1426
+ if (filter.cell_type) {
1427
+ filtered_cells = filtered_cells.filter(
1428
+ (cell) => matches_cell_type(cell, filter.cell_type)
1429
+ );
1430
+ }
1431
+ if (filter.ids && filter.ids.length > 0) {
1432
+ filtered_cells = filtered_cells.filter(
1433
+ (cell) => filter.ids.includes(cell.id)
1434
+ );
1435
+ }
1436
+ }
1437
+ const page = Math.max(0, options.page || 0);
1438
+ const page_size = Math.max(1, options.page_size || 50);
1439
+ const start_index = page * page_size;
1440
+ const paginated_ids = filtered_cells.slice(start_index, start_index + page_size).map((c) => c.id);
1441
+ const transformed_cells = [];
1442
+ for (const cell_id of paginated_ids) {
1443
+ const cell = cells[cell_id];
1444
+ if (cell) {
1445
+ const sanitized_cell = remove_circular_dependencies(cell);
1446
+ transformed_cells.push(sanitized_cell);
1447
+ }
1448
+ }
1449
+ return transformed_cells;
1450
+ }
1451
+ function list_layers(ui2) {
1452
+ const { editor } = ui2;
1453
+ const { graph } = editor;
1454
+ const model = graph.getModel();
1455
+ const root = model.getRoot();
1456
+ const layers = [];
1457
+ for (let i = 0; i < model.getChildCount(root); i++) {
1458
+ const layer = model.getChildAt(root, i);
1459
+ if (layer) {
1460
+ layers.push({
1461
+ id: layer.getId(),
1462
+ name: layer.getValue() || `Layer ${i}`,
1463
+ visible: layer.isVisible(),
1464
+ locked: !layer.isConnectable()
1465
+ });
1466
+ }
1467
+ }
1468
+ return layers;
1469
+ }
1470
+ function set_active_layer(ui2, options) {
1471
+ const { editor } = ui2;
1472
+ const { graph } = editor;
1473
+ const model = graph.getModel();
1474
+ const layer = model.getCell(options.layer_id);
1475
+ if (!layer) {
1476
+ throw new Error(`Layer with ID ${options.layer_id} not found`);
1477
+ }
1478
+ graph.setDefaultParent(layer);
1479
+ return {
1480
+ id: layer.getId(),
1481
+ name: layer.getValue() || "Unnamed Layer"
1482
+ };
1483
+ }
1484
+ function move_cell_to_layer(ui2, options) {
1485
+ const { editor } = ui2;
1486
+ const { graph } = editor;
1487
+ const model = graph.getModel();
1488
+ const cell = model.getCell(options.cell_id);
1489
+ const targetLayer = model.getCell(options.target_layer_id);
1490
+ if (!cell) {
1491
+ throw new Error(`Cell with ID ${options.cell_id} not found`);
1492
+ }
1493
+ if (!targetLayer) {
1494
+ throw new Error(
1495
+ `Target layer with ID ${options.target_layer_id} not found`
1496
+ );
1497
+ }
1498
+ model.beginUpdate();
1499
+ try {
1500
+ model.add(targetLayer, cell);
1501
+ } finally {
1502
+ model.endUpdate();
1503
+ }
1504
+ return {
1505
+ moved_cell: options.cell_id,
1506
+ to_layer: options.target_layer_id
1507
+ };
1508
+ }
1509
+ function get_active_layer(ui2) {
1510
+ const { editor } = ui2;
1511
+ const { graph } = editor;
1512
+ const activeLayer = graph.getDefaultParent();
1513
+ return {
1514
+ id: activeLayer.getId(),
1515
+ name: activeLayer.getValue() || "Default Layer"
1516
+ };
1517
+ }
1518
+ function create_layer(ui2, options) {
1519
+ const { editor } = ui2;
1520
+ const { graph } = editor;
1521
+ const model = graph.getModel();
1522
+ const root = model.getRoot();
1523
+ model.beginUpdate();
1524
+ let newLayer;
1525
+ try {
1526
+ newLayer = new window.mxCell(options.name);
1527
+ newLayer.setId(null);
1528
+ model.add(root, newLayer);
1529
+ } finally {
1530
+ model.endUpdate();
1531
+ }
1532
+ return {
1533
+ id: newLayer.getId(),
1534
+ name: options.name
1535
+ };
1536
+ }
1537
+
1538
+ // src/plugin/plugin.ts
1539
+ function reply_name(event_name, request_id) {
1540
+ return `${event_name}.${request_id}`;
1541
+ }
1542
+ var createToolHandler = (toolName, parameterKeys, executeFunction) => {
1543
+ return (request) => {
1544
+ const optionEntries = Object.entries(request).filter(([key, _value]) => {
1545
+ return parameterKeys.has(key);
1546
+ });
1547
+ const options = optionEntries.reduce(
1548
+ (acc, [key, value]) => {
1549
+ acc[key] = value;
1550
+ return acc;
1551
+ },
1552
+ {}
1553
+ );
1554
+ let reply;
1555
+ try {
1556
+ const result = executeFunction(ui, options);
1557
+ reply = {
1558
+ __event: reply_name(toolName, request.__request_id),
1559
+ __request_id: request.__request_id,
1560
+ success: true,
1561
+ result: remove_circular_dependencies(result)
1562
+ };
1563
+ } catch (error) {
1564
+ console.error(
1565
+ `[plugin] Tool ${toolName} failed for request ID ${request.__request_id}:`,
1566
+ error
1567
+ );
1568
+ reply = {
1569
+ __event: reply_name(toolName, request.__request_id),
1570
+ __request_id: request.__request_id,
1571
+ success: false,
1572
+ error: remove_circular_dependencies(error)
1573
+ };
1574
+ }
1575
+ if (wsManager) {
1576
+ wsManager.send(reply);
1577
+ }
1578
+ return reply;
1579
+ };
1580
+ };
1581
+ var ui;
1582
+ var wsManager = null;
1583
+ var settingsDialog = null;
1584
+ var toolDefinitions = [
1585
+ {
1586
+ name: "get-selected-cell",
1587
+ params: /* @__PURE__ */ new Set([]),
1588
+ handler: (ui2, _options) => {
1589
+ return ui2.editor.graph.getSelectionCell() || "no cell selected";
1590
+ }
1591
+ },
1592
+ {
1593
+ name: "add-rectangle",
1594
+ params: /* @__PURE__ */ new Set(["x", "y", "width", "height", "text", "style"]),
1595
+ handler: add_new_rectangle
1596
+ },
1597
+ {
1598
+ name: "delete-cell-by-id",
1599
+ params: /* @__PURE__ */ new Set(["cell_id"]),
1600
+ handler: delete_cell_by_id
1601
+ },
1602
+ {
1603
+ name: "add-edge",
1604
+ params: /* @__PURE__ */ new Set(["source_id", "target_id", "style", "text"]),
1605
+ handler: add_edge
1606
+ },
1607
+ {
1608
+ name: "get-shape-categories",
1609
+ params: /* @__PURE__ */ new Set([]),
1610
+ handler: get_shape_categories
1611
+ },
1612
+ {
1613
+ name: "get-shapes-in-category",
1614
+ params: /* @__PURE__ */ new Set(["category_id"]),
1615
+ handler: get_shapes_in_category
1616
+ },
1617
+ {
1618
+ name: "get-shape-by-name",
1619
+ params: /* @__PURE__ */ new Set(["shape_name"]),
1620
+ handler: get_shape_by_name
1621
+ },
1622
+ {
1623
+ name: "add-cell-of-shape",
1624
+ params: /* @__PURE__ */ new Set(["x", "y", "width", "height", "text", "style"]),
1625
+ handler: add_cell_of_shape
1626
+ },
1627
+ {
1628
+ name: "set-cell-shape",
1629
+ params: /* @__PURE__ */ new Set(["cell_id", "shape_name"]),
1630
+ handler: set_cell_shape
1631
+ },
1632
+ {
1633
+ name: "set-cell-data",
1634
+ params: /* @__PURE__ */ new Set(["cell_id", "key", "value"]),
1635
+ handler: (ui2, options) => {
1636
+ const mxUtils = window.mxUtils;
1637
+ return set_cell_data(mxUtils)(ui2, options);
1638
+ }
1639
+ },
1640
+ {
1641
+ name: "list-paged-model",
1642
+ params: /* @__PURE__ */ new Set(["page", "page_size", "filter"]),
1643
+ handler: list_paged_model
1644
+ },
1645
+ {
1646
+ name: "edit-cell",
1647
+ params: /* @__PURE__ */ new Set(["cell_id", "text", "x", "y", "width", "height", "style"]),
1648
+ handler: edit_cell
1649
+ },
1650
+ {
1651
+ name: "edit-edge",
1652
+ params: /* @__PURE__ */ new Set(["cell_id", "text", "source_id", "target_id", "style"]),
1653
+ handler: edit_edge
1654
+ },
1655
+ {
1656
+ name: "list-layers",
1657
+ params: /* @__PURE__ */ new Set([]),
1658
+ handler: list_layers
1659
+ },
1660
+ {
1661
+ name: "set-active-layer",
1662
+ params: /* @__PURE__ */ new Set(["layer_id"]),
1663
+ handler: set_active_layer
1664
+ },
1665
+ {
1666
+ name: "move-cell-to-layer",
1667
+ params: /* @__PURE__ */ new Set(["cell_id", "target_layer_id"]),
1668
+ handler: move_cell_to_layer
1669
+ },
1670
+ {
1671
+ name: "get-active-layer",
1672
+ params: /* @__PURE__ */ new Set([]),
1673
+ handler: get_active_layer
1674
+ },
1675
+ {
1676
+ name: "create-layer",
1677
+ params: /* @__PURE__ */ new Set(["name"]),
1678
+ handler: create_layer
1679
+ }
1680
+ ];
1681
+ var toolHandlers = /* @__PURE__ */ new Map();
1682
+ var handleWebSocketMessage = (message) => {
1683
+ console.debug("[plugin] Received WebSocket message:", message);
1684
+ if (message.__event && toolHandlers.has(message.__event)) {
1685
+ const handler = toolHandlers.get(message.__event);
1686
+ if (handler) {
1687
+ handler(message);
1688
+ }
1689
+ }
1690
+ };
1691
+ var initializeWebSocket = async () => {
1692
+ const config = await fetchPluginConfig();
1693
+ const wsUrl = buildWebSocketUrl(config);
1694
+ wsManager = createWebSocketManager({
1695
+ url: wsUrl,
1696
+ maxReconnectAttempts: 5,
1697
+ reconnectDelay: 3e3,
1698
+ pingInterval: 3e4
1699
+ });
1700
+ wsManager.onMessage(handleWebSocketMessage);
1701
+ wsManager.connect();
1702
+ console.log(`[plugin] WebSocket initialized with URL: ${wsUrl}`);
1703
+ };
1704
+ var initializeSettingsDialog = () => {
1705
+ const config = readPluginConfig();
1706
+ const connectionState = wsManager ? wsManager.getState() : "disconnected";
1707
+ const initialState = {
1708
+ config: { ...config },
1709
+ connectionState,
1710
+ isSaving: false,
1711
+ formData: {
1712
+ port: config.websocketPort.toString()
1713
+ },
1714
+ errors: {}
1715
+ };
1716
+ const actions = {
1717
+ onSave: (newConfig) => {
1718
+ writePluginConfig(newConfig);
1719
+ if (wsManager) {
1720
+ wsManager.disconnect();
1721
+ }
1722
+ initializeWebSocket();
1723
+ if (settingsDialog) {
1724
+ settingsDialog.update({
1725
+ ...initialState,
1726
+ config: { ...newConfig },
1727
+ connectionState: wsManager ? wsManager.getState() : "disconnected",
1728
+ isSaving: false
1729
+ });
1730
+ }
1731
+ console.log("[plugin] Configuration saved and WebSocket reinitialized");
1732
+ },
1733
+ onClose: () => {
1734
+ if (settingsDialog) {
1735
+ hideSettingsDialog(settingsDialog);
1736
+ }
1737
+ },
1738
+ onPing: async () => {
1739
+ if (wsManager) {
1740
+ return await wsManager.ping();
1741
+ }
1742
+ return false;
1743
+ },
1744
+ onReconnect: () => {
1745
+ if (wsManager) {
1746
+ wsManager.disconnect();
1747
+ wsManager.connect();
1748
+ }
1749
+ }
1750
+ };
1751
+ settingsDialog = createSettingsDialog(initialState, actions);
1752
+ };
1753
+ var showSettings = () => {
1754
+ if (!settingsDialog) {
1755
+ initializeSettingsDialog();
1756
+ }
1757
+ if (settingsDialog) {
1758
+ const config = readPluginConfig();
1759
+ const connectionState = wsManager ? wsManager.getState() : "disconnected";
1760
+ settingsDialog.update({
1761
+ config: { ...config },
1762
+ connectionState,
1763
+ isSaving: false,
1764
+ formData: {
1765
+ port: config.websocketPort.toString()
1766
+ },
1767
+ errors: {}
1768
+ });
1769
+ showSettingsDialog(settingsDialog);
1770
+ }
1771
+ };
1772
+ var addMenuItem = (ui2) => {
1773
+ if (!ui2.menus) {
1774
+ console.warn(
1775
+ "[plugin] Menu bar not available, cannot add MCP Settings menu item"
1776
+ );
1777
+ return;
1778
+ }
1779
+ const menubar = ui2.menus;
1780
+ try {
1781
+ let targetMenu = menubar.get("extras") || menubar.get("file") || menubar.get("edit");
1782
+ if (!targetMenu) {
1783
+ console.warn("[plugin] Could not find suitable menu to add MCP Settings");
1784
+ return;
1785
+ }
1786
+ ui2.actions.addAction("Draw.io MCP", function() {
1787
+ showSettings();
1788
+ });
1789
+ var oldFunct = targetMenu.funct;
1790
+ targetMenu.funct = function(targetMenu2, parent) {
1791
+ oldFunct.apply(this, arguments);
1792
+ ui2.menus.addMenuItems(targetMenu2, ["Draw.io MCP"], parent);
1793
+ };
1794
+ } catch (error) {
1795
+ console.error("[plugin] Failed to add menu item:", error);
1796
+ }
1797
+ };
1798
+ function initPlugin() {
1799
+ console.debug("[plugin] Loading Draw.io MCP Plugin...");
1800
+ const checkInterval = setInterval(() => {
1801
+ if (window.Draw) {
1802
+ clearInterval(checkInterval);
1803
+ window.Draw.loadPlugin((drawioUI) => {
1804
+ console.debug("[plugin] Plugin loaded successfully");
1805
+ ui = drawioUI;
1806
+ toolDefinitions.forEach((def) => {
1807
+ const handler = createToolHandler(def.name, def.params, def.handler);
1808
+ toolHandlers.set(def.name, handler);
1809
+ });
1810
+ initializeWebSocket();
1811
+ initializeSettingsDialog();
1812
+ addMenuItem(ui);
1813
+ console.info("[plugin] MCP Plugin fully initialized");
1814
+ });
1815
+ }
1816
+ }, 1e3);
1817
+ }
1818
+ if (typeof window !== "undefined") {
1819
+ if (document.readyState === "loading") {
1820
+ document.addEventListener("DOMContentLoaded", initPlugin);
1821
+ } else {
1822
+ initPlugin();
1823
+ }
1824
+ }
1825
+ })();