@drawsy/companion 0.1.33 → 0.1.34
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/drawsy/bridge.js +32 -26
- package/dist/drawsy/codex-app-server.js +140 -131
- package/dist/drawsy/mcp.js +129 -0
- package/dist/drawsy/protocol.js +73 -0
- package/package.json +1 -1
package/dist/drawsy/bridge.js
CHANGED
|
@@ -8,7 +8,7 @@ import { LocalConversationStore } from "./local-conversation-store.js";
|
|
|
8
8
|
import { normalizeFolder, pickFolder } from "./folder-picker.js";
|
|
9
9
|
import { readLocalEngineStatus } from "./engine-status.js";
|
|
10
10
|
import { createCanvasImageAsset, createCanvasImageAssetFromBytes, createCanvasImageFileFromBytes, inspectCanvasImage } from "./image-asset.js";
|
|
11
|
-
import { CANVAS_REQUEST_TIMEOUT_MS, MAX_CANVAS_ASSET_BYTES, MAX_BODY_BYTES, isRecord, parseCanvasContextReference, parseCanvasContextRequest, parseCanvasConnectorRequest, parseCanvasDiagramCodeRequest, parseCanvasLabelRequest, parseCanvasImageRequest, parseLivePreviewRequest, parseCanvasOperations, parseAgentConnectorTurn, parseAgentResourceTurn, parseDrawsyTabId, parseDrawsyTabUrl, parseGenerationMode, isConnectorCapability, } from "./protocol.js";
|
|
11
|
+
import { CANVAS_REQUEST_TIMEOUT_MS, MAX_CANVAS_ASSET_BYTES, MAX_BODY_BYTES, isRecord, parseCanvasContextReference, parseCanvasContextRequest, parseCanvasConnectorRequest, parseCanvasDiagramCodeRequest, parseCanvasLabelRequest, parseCanvasLibraryRequest, parseCanvasImageRequest, parseLivePreviewRequest, parseCanvasOperations, parseAgentConnectorTurn, parseAgentResourceTurn, parseDrawsyTabId, parseDrawsyTabUrl, parseGenerationMode, isConnectorCapability, } from "./protocol.js";
|
|
12
12
|
import { createConnectorBackendResolver } from "./connector-backend.js";
|
|
13
13
|
const MAX_DRAW_DOCUMENT_BYTES = 512 * 1024;
|
|
14
14
|
const readDrawDocument = async (folder) => {
|
|
@@ -70,7 +70,8 @@ const assertCanvasActionAllowed = (session, action) => {
|
|
|
70
70
|
"context",
|
|
71
71
|
"replace-image",
|
|
72
72
|
"replaceImage",
|
|
73
|
-
"preview"
|
|
73
|
+
"preview",
|
|
74
|
+
"library"
|
|
74
75
|
].includes(action)) {
|
|
75
76
|
throw new BridgeRequestError(403, "fast_mode_action_blocked", "Fast Mode does not allow this canvas action.");
|
|
76
77
|
}
|
|
@@ -892,7 +893,7 @@ export const createDrawsyBridge = (options = {}) => {
|
|
|
892
893
|
response.end();
|
|
893
894
|
return;
|
|
894
895
|
}
|
|
895
|
-
const internalCanvas = url.pathname.match(/^\/internal\/sessions\/([^/]+)\/canvas\/(read|capabilities|connector|label|diagram|apply|inspect|image|context|replace-image|preview)$/);
|
|
896
|
+
const internalCanvas = url.pathname.match(/^\/internal\/sessions\/([^/]+)\/canvas\/(read|capabilities|connector|label|diagram|apply|inspect|image|context|replace-image|preview|library)$/);
|
|
896
897
|
if (request.method === "POST" && internalCanvas) {
|
|
897
898
|
const session = internalSession(request, response, decodeURIComponent(internalCanvas[1]));
|
|
898
899
|
if (!session)
|
|
@@ -916,30 +917,34 @@ export const createDrawsyBridge = (options = {}) => {
|
|
|
916
917
|
? await requestCanvas(session, "preview", {
|
|
917
918
|
previewRequest: parsedPreview
|
|
918
919
|
})
|
|
919
|
-
: action === "
|
|
920
|
-
? await requestCanvas(session, "
|
|
921
|
-
|
|
920
|
+
: action === "library"
|
|
921
|
+
? await requestCanvas(session, "library", {
|
|
922
|
+
libraryRequest: parseCanvasLibraryRequest(body)
|
|
922
923
|
})
|
|
923
|
-
: action === "
|
|
924
|
-
?
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
924
|
+
: action === "diagram"
|
|
925
|
+
? await requestCanvas(session, "diagram", {
|
|
926
|
+
diagramRequest: parsedDiagram
|
|
927
|
+
})
|
|
928
|
+
: action === "context"
|
|
929
|
+
? resolveContextCaptures(session, [
|
|
930
|
+
parseCanvasContextReference(await requestCanvas(session, "capture", {
|
|
931
|
+
contextRequest: parseCanvasContextRequest(body)
|
|
932
|
+
}))
|
|
933
|
+
])[0]
|
|
934
|
+
: await requestCanvas(session, action, action === "apply"
|
|
935
|
+
? {
|
|
936
|
+
operations: {
|
|
937
|
+
...parseCanvasOperations(body),
|
|
938
|
+
...(session.generationMode === "fast"
|
|
939
|
+
? { existingElementsOnly: true }
|
|
940
|
+
: {})
|
|
941
|
+
}
|
|
936
942
|
}
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
: undefined);
|
|
943
|
+
: action === "connector"
|
|
944
|
+
? { connectorRequest: parseCanvasConnectorRequest(body) }
|
|
945
|
+
: action === "label"
|
|
946
|
+
? { labelRequest: parseCanvasLabelRequest(body) }
|
|
947
|
+
: undefined);
|
|
943
948
|
json(response, 200, result);
|
|
944
949
|
return;
|
|
945
950
|
}
|
|
@@ -1021,7 +1026,8 @@ export const createDrawsyBridge = (options = {}) => {
|
|
|
1021
1026
|
if (request.method === "GET" && url.pathname === "/v1/engines") {
|
|
1022
1027
|
json(response, 200, {
|
|
1023
1028
|
engines: readLocalEngineStatus(),
|
|
1024
|
-
generationModes: ["draw", "fast"]
|
|
1029
|
+
generationModes: ["draw", "fast"],
|
|
1030
|
+
library: true
|
|
1025
1031
|
});
|
|
1026
1032
|
return;
|
|
1027
1033
|
}
|
|
@@ -41,199 +41,205 @@ const describeToolItem = (item) => {
|
|
|
41
41
|
const server = typeof item.server === "string" ? item.server : "MCP";
|
|
42
42
|
const drawsyMessages = item.tool === "read_current_canvas"
|
|
43
43
|
? { started: "Reading current canvas", completed: "Canvas read" }
|
|
44
|
-
: item.tool === "
|
|
45
|
-
? { started: "
|
|
46
|
-
: item.tool === "
|
|
47
|
-
? { started: "
|
|
48
|
-
: item.tool === "
|
|
49
|
-
? { started: "
|
|
50
|
-
: item.tool === "
|
|
51
|
-
? { started: "
|
|
52
|
-
: item.tool === "
|
|
53
|
-
? { started: "
|
|
54
|
-
: item.tool === "
|
|
55
|
-
? { started: "
|
|
56
|
-
: item.tool === "
|
|
57
|
-
? {
|
|
58
|
-
|
|
59
|
-
completed: "
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
started: "Replacing canvas image",
|
|
64
|
-
completed: "Image replaced",
|
|
65
|
-
}
|
|
66
|
-
: item.tool === "list_connected_sources"
|
|
67
|
-
? {
|
|
68
|
-
started: "Checking connected sources",
|
|
69
|
-
completed: "Sources ready",
|
|
70
|
-
}
|
|
71
|
-
: item.tool === "search_connected_source"
|
|
44
|
+
: item.tool === "search_library"
|
|
45
|
+
? { started: "Searching library", completed: "Library searched" }
|
|
46
|
+
: item.tool === "read_library_item"
|
|
47
|
+
? { started: "Reading library item", completed: "Library item read" }
|
|
48
|
+
: item.tool === "insert_library_item"
|
|
49
|
+
? { started: "Inserting library item", completed: "Library item inserted" }
|
|
50
|
+
: item.tool === "get_canvas_capabilities"
|
|
51
|
+
? { started: "Checking canvas tools", completed: "Canvas tools ready" }
|
|
52
|
+
: item.tool === "create_or_update_connector"
|
|
53
|
+
? { started: "Connecting canvas objects", completed: "Objects connected" }
|
|
54
|
+
: item.tool === "set_container_label"
|
|
55
|
+
? { started: "Setting container label", completed: "Label set" }
|
|
56
|
+
: item.tool === "apply_canvas_changes"
|
|
57
|
+
? { started: "Updating canvas", completed: "Canvas updated" }
|
|
58
|
+
: item.tool === "inspect_current_canvas_layout"
|
|
59
|
+
? { started: "Inspecting canvas layout", completed: "Layout checked" }
|
|
60
|
+
: item.tool === "add_image_from_file"
|
|
61
|
+
? { started: "Adding image to canvas", completed: "Image added" }
|
|
62
|
+
: item.tool === "capture_canvas_context"
|
|
72
63
|
? {
|
|
73
|
-
started: "
|
|
74
|
-
completed: "
|
|
64
|
+
started: "Capturing canvas context",
|
|
65
|
+
completed: "Context captured",
|
|
75
66
|
}
|
|
76
|
-
: item.tool === "
|
|
67
|
+
: item.tool === "replace_canvas_image_from_file"
|
|
77
68
|
? {
|
|
78
|
-
started: "
|
|
79
|
-
completed: "
|
|
69
|
+
started: "Replacing canvas image",
|
|
70
|
+
completed: "Image replaced",
|
|
80
71
|
}
|
|
81
|
-
: item.tool === "
|
|
72
|
+
: item.tool === "list_connected_sources"
|
|
82
73
|
? {
|
|
83
|
-
started: "
|
|
84
|
-
completed: "
|
|
74
|
+
started: "Checking connected sources",
|
|
75
|
+
completed: "Sources ready",
|
|
85
76
|
}
|
|
86
|
-
: item.tool === "
|
|
77
|
+
: item.tool === "search_connected_source"
|
|
87
78
|
? {
|
|
88
|
-
started: "
|
|
89
|
-
completed: "
|
|
79
|
+
started: "Searching connected source",
|
|
80
|
+
completed: "Source searched",
|
|
90
81
|
}
|
|
91
|
-
: item.tool === "
|
|
82
|
+
: item.tool === "list_connected_meeting_tools"
|
|
92
83
|
? {
|
|
93
|
-
started: "
|
|
94
|
-
completed: "
|
|
84
|
+
started: "Checking meeting tools",
|
|
85
|
+
completed: "Meeting tools ready",
|
|
95
86
|
}
|
|
96
|
-
: item.tool === "
|
|
87
|
+
: item.tool === "call_connected_meeting_tool"
|
|
97
88
|
? {
|
|
98
|
-
started: "
|
|
99
|
-
completed: "
|
|
89
|
+
started: "Reading meeting source",
|
|
90
|
+
completed: "Meeting source ready",
|
|
100
91
|
}
|
|
101
|
-
: item.tool === "
|
|
102
|
-
? {
|
|
103
|
-
|
|
92
|
+
: item.tool === "list_aws_regions"
|
|
93
|
+
? {
|
|
94
|
+
started: "Checking AWS regions",
|
|
95
|
+
completed: "AWS regions ready",
|
|
96
|
+
}
|
|
97
|
+
: item.tool === "search_aws_resources"
|
|
104
98
|
? {
|
|
105
|
-
started: "
|
|
106
|
-
completed: "
|
|
99
|
+
started: "Searching AWS infrastructure",
|
|
100
|
+
completed: "AWS resources ready",
|
|
107
101
|
}
|
|
108
|
-
: item.tool === "
|
|
102
|
+
: item.tool === "list_aws_cloudformation_stacks"
|
|
109
103
|
? {
|
|
110
|
-
started: "Checking
|
|
111
|
-
completed: "
|
|
104
|
+
started: "Checking CloudFormation",
|
|
105
|
+
completed: "CloudFormation stacks ready",
|
|
112
106
|
}
|
|
113
|
-
: item.tool === "
|
|
114
|
-
? {
|
|
115
|
-
|
|
116
|
-
completed: "Drive files ready",
|
|
117
|
-
}
|
|
118
|
-
: item.tool === "list_github_repositories"
|
|
107
|
+
: item.tool === "list_mail_messages"
|
|
108
|
+
? { started: "Checking mail", completed: "Mail ready" }
|
|
109
|
+
: item.tool === "list_calendars"
|
|
119
110
|
? {
|
|
120
|
-
started: "Checking
|
|
121
|
-
completed: "
|
|
111
|
+
started: "Checking calendars",
|
|
112
|
+
completed: "Calendars ready",
|
|
122
113
|
}
|
|
123
|
-
: item.tool === "
|
|
114
|
+
: item.tool === "list_calendar_events"
|
|
124
115
|
? {
|
|
125
|
-
started: "
|
|
126
|
-
completed: "
|
|
116
|
+
started: "Checking calendar",
|
|
117
|
+
completed: "Events ready",
|
|
127
118
|
}
|
|
128
|
-
: item.tool === "
|
|
119
|
+
: item.tool === "list_drive_files"
|
|
129
120
|
? {
|
|
130
|
-
started: "Checking
|
|
131
|
-
completed: "
|
|
121
|
+
started: "Checking Drive",
|
|
122
|
+
completed: "Drive files ready",
|
|
132
123
|
}
|
|
133
|
-
: item.tool === "
|
|
124
|
+
: item.tool === "list_github_repositories"
|
|
134
125
|
? {
|
|
135
|
-
started: "Checking
|
|
136
|
-
completed: "
|
|
126
|
+
started: "Checking repositories",
|
|
127
|
+
completed: "Repositories ready",
|
|
137
128
|
}
|
|
138
|
-
: item.tool === "
|
|
129
|
+
: item.tool === "list_github_repository_contents"
|
|
139
130
|
? {
|
|
140
|
-
started: "
|
|
141
|
-
completed: "
|
|
131
|
+
started: "Browsing repository",
|
|
132
|
+
completed: "Repository contents ready",
|
|
142
133
|
}
|
|
143
|
-
: item.tool === "
|
|
134
|
+
: item.tool === "list_github_issues"
|
|
144
135
|
? {
|
|
145
|
-
started: "Checking
|
|
146
|
-
completed: "
|
|
136
|
+
started: "Checking issues",
|
|
137
|
+
completed: "Issues ready",
|
|
147
138
|
}
|
|
148
|
-
: item.tool === "
|
|
139
|
+
: item.tool === "list_github_pull_requests"
|
|
149
140
|
? {
|
|
150
|
-
started: "Checking
|
|
151
|
-
completed: "
|
|
141
|
+
started: "Checking pull requests",
|
|
142
|
+
completed: "Pull requests ready",
|
|
152
143
|
}
|
|
153
|
-
: item.tool === "
|
|
144
|
+
: item.tool === "list_notion_content"
|
|
154
145
|
? {
|
|
155
|
-
started: "
|
|
156
|
-
completed: "
|
|
146
|
+
started: "Checking Notion",
|
|
147
|
+
completed: "Notion content ready",
|
|
157
148
|
}
|
|
158
|
-
: item.tool === "
|
|
149
|
+
: item.tool === "list_slack_channels"
|
|
159
150
|
? {
|
|
160
|
-
started: "Checking
|
|
161
|
-
completed: "
|
|
151
|
+
started: "Checking Slack channels",
|
|
152
|
+
completed: "Channels ready",
|
|
162
153
|
}
|
|
163
|
-
: item.tool === "
|
|
154
|
+
: item.tool === "list_slack_messages"
|
|
164
155
|
? {
|
|
165
|
-
started: "
|
|
166
|
-
completed: "
|
|
156
|
+
started: "Checking Slack",
|
|
157
|
+
completed: "Slack messages ready",
|
|
167
158
|
}
|
|
168
|
-
: item.tool === "
|
|
159
|
+
: item.tool === "read_connected_item"
|
|
169
160
|
? {
|
|
170
|
-
started: "
|
|
171
|
-
completed: "
|
|
161
|
+
started: "Reading connected item",
|
|
162
|
+
completed: "Source read",
|
|
172
163
|
}
|
|
173
|
-
: item.tool === "
|
|
164
|
+
: item.tool === "list_kanban_boards"
|
|
174
165
|
? {
|
|
175
|
-
started: "
|
|
176
|
-
completed: "
|
|
166
|
+
started: "Checking Kanban boards",
|
|
167
|
+
completed: "Boards ready",
|
|
177
168
|
}
|
|
178
|
-
: item.tool === "
|
|
169
|
+
: item.tool === "read_kanban_board"
|
|
179
170
|
? {
|
|
180
|
-
started: "
|
|
181
|
-
completed: "
|
|
171
|
+
started: "Reading Kanban board",
|
|
172
|
+
completed: "Board ready",
|
|
182
173
|
}
|
|
183
|
-
: item.tool === "
|
|
174
|
+
: item.tool === "create_kanban_card"
|
|
184
175
|
? {
|
|
185
|
-
started: "
|
|
186
|
-
completed: "
|
|
176
|
+
started: "Creating Kanban card",
|
|
177
|
+
completed: "Card created",
|
|
187
178
|
}
|
|
188
|
-
: item.tool === "
|
|
179
|
+
: item.tool === "update_kanban_card"
|
|
189
180
|
? {
|
|
190
|
-
started: "Updating
|
|
191
|
-
completed: "
|
|
181
|
+
started: "Updating Kanban card",
|
|
182
|
+
completed: "Card updated",
|
|
192
183
|
}
|
|
193
|
-
: item.tool === "
|
|
184
|
+
: item.tool === "move_kanban_card"
|
|
194
185
|
? {
|
|
195
|
-
started: "
|
|
196
|
-
completed: "
|
|
186
|
+
started: "Moving Kanban card",
|
|
187
|
+
completed: "Card moved",
|
|
197
188
|
}
|
|
198
|
-
: item.tool === "
|
|
189
|
+
: item.tool === "create_kanban_checklist_item"
|
|
199
190
|
? {
|
|
200
|
-
started: "
|
|
201
|
-
completed: "
|
|
191
|
+
started: "Adding checklist item",
|
|
192
|
+
completed: "Checklist updated",
|
|
202
193
|
}
|
|
203
|
-
: item.tool === "
|
|
194
|
+
: item.tool === "update_kanban_checklist_item"
|
|
204
195
|
? {
|
|
205
|
-
started: "
|
|
206
|
-
completed: "
|
|
196
|
+
started: "Updating checklist",
|
|
197
|
+
completed: "Checklist updated",
|
|
207
198
|
}
|
|
208
|
-
: item.tool === "
|
|
199
|
+
: item.tool === "link_current_canvas_to_kanban_card"
|
|
209
200
|
? {
|
|
210
|
-
started: "
|
|
211
|
-
completed: "
|
|
201
|
+
started: "Linking current canvas",
|
|
202
|
+
completed: "Canvas linked",
|
|
212
203
|
}
|
|
213
|
-
: item.tool === "
|
|
204
|
+
: item.tool === "list_jira_connections"
|
|
214
205
|
? {
|
|
215
|
-
started: "
|
|
216
|
-
completed: "
|
|
206
|
+
started: "Checking Jira connections",
|
|
207
|
+
completed: "Jira ready",
|
|
217
208
|
}
|
|
218
|
-
: item.tool === "
|
|
209
|
+
: item.tool === "list_jira_projects"
|
|
219
210
|
? {
|
|
220
|
-
started: "Checking Jira
|
|
221
|
-
completed: "
|
|
211
|
+
started: "Checking Jira projects",
|
|
212
|
+
completed: "Projects ready",
|
|
222
213
|
}
|
|
223
|
-
: item.tool === "
|
|
214
|
+
: item.tool === "search_jira_issues"
|
|
224
215
|
? {
|
|
225
|
-
started: "
|
|
226
|
-
completed: "
|
|
216
|
+
started: "Searching Jira issues",
|
|
217
|
+
completed: "Issues ready",
|
|
227
218
|
}
|
|
228
|
-
: item.tool === "
|
|
219
|
+
: item.tool === "read_jira_issue"
|
|
229
220
|
? {
|
|
230
|
-
started: "
|
|
231
|
-
completed: "
|
|
221
|
+
started: "Reading Jira issue",
|
|
222
|
+
completed: "Issue ready",
|
|
232
223
|
}
|
|
233
|
-
:
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
224
|
+
: item.tool === "list_jira_boards"
|
|
225
|
+
? {
|
|
226
|
+
started: "Checking Jira boards",
|
|
227
|
+
completed: "Boards ready",
|
|
228
|
+
}
|
|
229
|
+
: item.tool === "list_jira_sprints"
|
|
230
|
+
? {
|
|
231
|
+
started: "Checking Jira sprints",
|
|
232
|
+
completed: "Sprints ready",
|
|
233
|
+
}
|
|
234
|
+
: item.tool === "list_jira_backlog"
|
|
235
|
+
? {
|
|
236
|
+
started: "Checking Jira backlog",
|
|
237
|
+
completed: "Backlog ready",
|
|
238
|
+
}
|
|
239
|
+
: {
|
|
240
|
+
started: "Working on the canvas",
|
|
241
|
+
completed: "Canvas tool finished",
|
|
242
|
+
};
|
|
237
243
|
return {
|
|
238
244
|
tool: server === "drawsy" ? item.tool : `${server}/${item.tool}`,
|
|
239
245
|
startedMessage: server === "drawsy" ? drawsyMessages.started : `Using ${item.tool}`,
|
|
@@ -1145,6 +1151,9 @@ export class CodexAppServer {
|
|
|
1145
1151
|
default_tools_approval_mode: "auto",
|
|
1146
1152
|
tools: {
|
|
1147
1153
|
apply_canvas_changes: { approval_mode: "approve" },
|
|
1154
|
+
search_library: { approval_mode: "approve" },
|
|
1155
|
+
read_library_item: { approval_mode: "approve" },
|
|
1156
|
+
insert_library_item: { approval_mode: "approve" },
|
|
1148
1157
|
render_diagram_code: { approval_mode: "approve" },
|
|
1149
1158
|
create_or_update_connector: { approval_mode: "approve" },
|
|
1150
1159
|
set_container_label: { approval_mode: "approve" },
|
package/dist/drawsy/mcp.js
CHANGED
|
@@ -29934,6 +29934,65 @@ var StdioServerTransport = class {
|
|
|
29934
29934
|
var MAX_BODY_BYTES = 12 * 1024 * 1024;
|
|
29935
29935
|
var MAX_CANVAS_ASSET_BYTES = 8 * 1024 * 1024;
|
|
29936
29936
|
var MAX_DIAGRAM_SOURCE_BYTES = 256 * 1024;
|
|
29937
|
+
var parseCanvasLibraryRequest = (value) => {
|
|
29938
|
+
if (!isRecord(value)) throw new Error("Library request must be an object.");
|
|
29939
|
+
const boundedString = (key, max, required2 = false) => {
|
|
29940
|
+
const entry = value[key];
|
|
29941
|
+
if (entry === void 0 && !required2) return void 0;
|
|
29942
|
+
if (typeof entry !== "string" || !entry.trim() || entry.length > max)
|
|
29943
|
+
throw new Error(`Library ${key} is invalid.`);
|
|
29944
|
+
return entry.trim();
|
|
29945
|
+
};
|
|
29946
|
+
const pagination = () => {
|
|
29947
|
+
const cursor = boundedString("cursor", 4096);
|
|
29948
|
+
const limit = value.limit;
|
|
29949
|
+
if (limit !== void 0 && (typeof limit !== "number" || !Number.isInteger(limit) || limit < 1 || limit > 50))
|
|
29950
|
+
throw new Error("Library limit must be an integer from 1 to 50.");
|
|
29951
|
+
return {
|
|
29952
|
+
...cursor ? { cursor } : {},
|
|
29953
|
+
...limit !== void 0 ? { limit } : {}
|
|
29954
|
+
};
|
|
29955
|
+
};
|
|
29956
|
+
const source = value.source;
|
|
29957
|
+
if (source !== void 0 && source !== "public")
|
|
29958
|
+
throw new Error("Only the public library catalog is available.");
|
|
29959
|
+
if (value.action === "search") {
|
|
29960
|
+
const query = boundedString("query", 256);
|
|
29961
|
+
return {
|
|
29962
|
+
action: "search",
|
|
29963
|
+
...query ? { query } : {},
|
|
29964
|
+
source: "public",
|
|
29965
|
+
...pagination()
|
|
29966
|
+
};
|
|
29967
|
+
}
|
|
29968
|
+
if (value.action === "read" || value.action === "insert") {
|
|
29969
|
+
const packId = boundedString("packId", 256, true);
|
|
29970
|
+
const itemId = boundedString("itemId", 256, value.action === "insert");
|
|
29971
|
+
if (value.action === "read") {
|
|
29972
|
+
return {
|
|
29973
|
+
action: "read",
|
|
29974
|
+
source: "public",
|
|
29975
|
+
packId,
|
|
29976
|
+
...itemId ? { itemId } : {},
|
|
29977
|
+
...pagination()
|
|
29978
|
+
};
|
|
29979
|
+
}
|
|
29980
|
+
const { x, y } = value;
|
|
29981
|
+
if (typeof x !== "number" || !Number.isFinite(x) || Math.abs(x) > 1e6 || typeof y !== "number" || !Number.isFinite(y) || Math.abs(y) > 1e6)
|
|
29982
|
+
throw new Error("Library insertion coordinates are invalid.");
|
|
29983
|
+
const validOperationId = boundedString("operationId", 128, true);
|
|
29984
|
+
return {
|
|
29985
|
+
action: "insert",
|
|
29986
|
+
source: "public",
|
|
29987
|
+
packId,
|
|
29988
|
+
itemId,
|
|
29989
|
+
x,
|
|
29990
|
+
y,
|
|
29991
|
+
operationId: validOperationId
|
|
29992
|
+
};
|
|
29993
|
+
}
|
|
29994
|
+
throw new Error("Library action is invalid.");
|
|
29995
|
+
};
|
|
29937
29996
|
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
29938
29997
|
var renderedElementType = (element) => {
|
|
29939
29998
|
const type = typeof element.type === "string" ? element.type : "unknown";
|
|
@@ -29950,6 +30009,9 @@ var renderedElementType = (element) => {
|
|
|
29950
30009
|
return rounded ? "rounded diamond" : "diamond";
|
|
29951
30010
|
}
|
|
29952
30011
|
if (type === "rectangle") {
|
|
30012
|
+
if (typeof element.shapeKind === "string" && element.shapeKind.trim()) {
|
|
30013
|
+
return element.shapeKind;
|
|
30014
|
+
}
|
|
29953
30015
|
return rounded ? "rounded rectangle" : "rectangle";
|
|
29954
30016
|
}
|
|
29955
30017
|
return type;
|
|
@@ -30582,6 +30644,73 @@ if (surfaceKind === "canvas" || surfaceKind === "presentation") {
|
|
|
30582
30644
|
}
|
|
30583
30645
|
);
|
|
30584
30646
|
}
|
|
30647
|
+
if (surfaceKind === "canvas" || surfaceKind === "presentation") {
|
|
30648
|
+
const libraryCall = async (input) => {
|
|
30649
|
+
try {
|
|
30650
|
+
const parsed = parseCanvasLibraryRequest(input);
|
|
30651
|
+
const result = JSON.parse(await callBridge("library", parsed));
|
|
30652
|
+
return {
|
|
30653
|
+
content: [{ type: "text", text: JSON.stringify(result) }]
|
|
30654
|
+
};
|
|
30655
|
+
} catch (error48) {
|
|
30656
|
+
return {
|
|
30657
|
+
isError: true,
|
|
30658
|
+
content: [
|
|
30659
|
+
{
|
|
30660
|
+
type: "text",
|
|
30661
|
+
text: error48 instanceof Error ? error48.message : "Library request failed."
|
|
30662
|
+
}
|
|
30663
|
+
]
|
|
30664
|
+
};
|
|
30665
|
+
}
|
|
30666
|
+
};
|
|
30667
|
+
const optionalPage = {
|
|
30668
|
+
cursor: external_exports3.string().trim().min(1).max(4096).optional(),
|
|
30669
|
+
limit: external_exports3.number().int().min(1).max(50).optional()
|
|
30670
|
+
};
|
|
30671
|
+
server.registerTool(
|
|
30672
|
+
"search_library",
|
|
30673
|
+
{
|
|
30674
|
+
description: "Search the public catalog for packs and items.",
|
|
30675
|
+
inputSchema: external_exports3.object({
|
|
30676
|
+
query: external_exports3.string().trim().min(1).max(256).optional(),
|
|
30677
|
+
...optionalPage
|
|
30678
|
+
}).strict(),
|
|
30679
|
+
annotations: { readOnlyHint: true, destructiveHint: false }
|
|
30680
|
+
},
|
|
30681
|
+
(input) => libraryCall({ ...input, action: "search" })
|
|
30682
|
+
);
|
|
30683
|
+
server.registerTool(
|
|
30684
|
+
"read_library_item",
|
|
30685
|
+
{
|
|
30686
|
+
description: "Read public library items or list a pack\u2019s items.",
|
|
30687
|
+
inputSchema: external_exports3.object({
|
|
30688
|
+
packId: external_exports3.string().trim().min(1).max(256),
|
|
30689
|
+
itemId: external_exports3.string().trim().min(1).max(256).optional(),
|
|
30690
|
+
...optionalPage
|
|
30691
|
+
}).strict(),
|
|
30692
|
+
annotations: { readOnlyHint: true, destructiveHint: false }
|
|
30693
|
+
},
|
|
30694
|
+
(input) => libraryCall({ ...input, action: "read" })
|
|
30695
|
+
);
|
|
30696
|
+
server.registerTool(
|
|
30697
|
+
"insert_library_item",
|
|
30698
|
+
{
|
|
30699
|
+
description: "Insert a library item at canvas coordinates x and y, measured from its top-left corner. Returns element IDs usable with the canvas connector tool.",
|
|
30700
|
+
inputSchema: external_exports3.object({
|
|
30701
|
+
packId: external_exports3.string().trim().min(1).max(256),
|
|
30702
|
+
itemId: external_exports3.string().trim().min(1).max(256),
|
|
30703
|
+
x: external_exports3.number().finite().min(-1e6).max(1e6),
|
|
30704
|
+
y: external_exports3.number().finite().min(-1e6).max(1e6),
|
|
30705
|
+
operationId: external_exports3.string().trim().min(1).max(128).describe(
|
|
30706
|
+
"Insertion identifier; reuse for retries of the same insertion."
|
|
30707
|
+
)
|
|
30708
|
+
}).strict(),
|
|
30709
|
+
annotations: { readOnlyHint: false, destructiveHint: false }
|
|
30710
|
+
},
|
|
30711
|
+
(input) => libraryCall({ ...input, action: "insert" })
|
|
30712
|
+
);
|
|
30713
|
+
}
|
|
30585
30714
|
server.registerTool(
|
|
30586
30715
|
"list_connected_sources",
|
|
30587
30716
|
{
|
package/dist/drawsy/protocol.js
CHANGED
|
@@ -10,6 +10,76 @@ export const parseGenerationMode = (value) => {
|
|
|
10
10
|
throw new Error("generationMode must be 'fast' or 'draw'.");
|
|
11
11
|
};
|
|
12
12
|
export const surfaceSupportsLivePreview = (surfaceKind) => surfaceKind === "canvas" || surfaceKind === "presentation";
|
|
13
|
+
export const parseCanvasLibraryRequest = (value) => {
|
|
14
|
+
if (!isRecord(value))
|
|
15
|
+
throw new Error("Library request must be an object.");
|
|
16
|
+
const boundedString = (key, max, required = false) => {
|
|
17
|
+
const entry = value[key];
|
|
18
|
+
if (entry === undefined && !required)
|
|
19
|
+
return undefined;
|
|
20
|
+
if (typeof entry !== "string" || !entry.trim() || entry.length > max)
|
|
21
|
+
throw new Error(`Library ${key} is invalid.`);
|
|
22
|
+
return entry.trim();
|
|
23
|
+
};
|
|
24
|
+
const pagination = () => {
|
|
25
|
+
const cursor = boundedString("cursor", 4_096);
|
|
26
|
+
const limit = value.limit;
|
|
27
|
+
if (limit !== undefined &&
|
|
28
|
+
(typeof limit !== "number" ||
|
|
29
|
+
!Number.isInteger(limit) ||
|
|
30
|
+
limit < 1 ||
|
|
31
|
+
limit > 50))
|
|
32
|
+
throw new Error("Library limit must be an integer from 1 to 50.");
|
|
33
|
+
return {
|
|
34
|
+
...(cursor ? { cursor } : {}),
|
|
35
|
+
...(limit !== undefined ? { limit } : {})
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
const source = value.source;
|
|
39
|
+
if (source !== undefined && source !== "public")
|
|
40
|
+
throw new Error("Only the public library catalog is available.");
|
|
41
|
+
if (value.action === "search") {
|
|
42
|
+
const query = boundedString("query", 256);
|
|
43
|
+
return {
|
|
44
|
+
action: "search",
|
|
45
|
+
...(query ? { query } : {}),
|
|
46
|
+
source: "public",
|
|
47
|
+
...pagination()
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
if (value.action === "read" || value.action === "insert") {
|
|
51
|
+
const packId = boundedString("packId", 256, true);
|
|
52
|
+
const itemId = boundedString("itemId", 256, value.action === "insert");
|
|
53
|
+
if (value.action === "read") {
|
|
54
|
+
return {
|
|
55
|
+
action: "read",
|
|
56
|
+
source: "public",
|
|
57
|
+
packId,
|
|
58
|
+
...(itemId ? { itemId } : {}),
|
|
59
|
+
...pagination()
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const { x, y } = value;
|
|
63
|
+
if (typeof x !== "number" ||
|
|
64
|
+
!Number.isFinite(x) ||
|
|
65
|
+
Math.abs(x) > 1_000_000 ||
|
|
66
|
+
typeof y !== "number" ||
|
|
67
|
+
!Number.isFinite(y) ||
|
|
68
|
+
Math.abs(y) > 1_000_000)
|
|
69
|
+
throw new Error("Library insertion coordinates are invalid.");
|
|
70
|
+
const validOperationId = boundedString("operationId", 128, true);
|
|
71
|
+
return {
|
|
72
|
+
action: "insert",
|
|
73
|
+
source: "public",
|
|
74
|
+
packId,
|
|
75
|
+
itemId: itemId,
|
|
76
|
+
x,
|
|
77
|
+
y,
|
|
78
|
+
operationId: validOperationId
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
throw new Error("Library action is invalid.");
|
|
82
|
+
};
|
|
13
83
|
export const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
14
84
|
export const parseDrawsyTabId = (value) => {
|
|
15
85
|
if (value === undefined || value === null) {
|
|
@@ -61,6 +131,9 @@ const renderedElementType = (element) => {
|
|
|
61
131
|
return rounded ? "rounded diamond" : "diamond";
|
|
62
132
|
}
|
|
63
133
|
if (type === "rectangle") {
|
|
134
|
+
if (typeof element.shapeKind === "string" && element.shapeKind.trim()) {
|
|
135
|
+
return element.shapeKind;
|
|
136
|
+
}
|
|
64
137
|
return rounded ? "rounded rectangle" : "rectangle";
|
|
65
138
|
}
|
|
66
139
|
return type;
|