@particle-academy/agent-integrations 0.2.4 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bridges/charts.d.cts +39 -0
- package/dist/bridges/charts.d.ts +39 -0
- package/dist/bridges/code.d.cts +47 -0
- package/dist/bridges/code.d.ts +47 -0
- package/dist/bridges/flow.d.cts +3 -2
- package/dist/bridges/flow.d.ts +3 -2
- package/dist/bridges/forms.d.cts +76 -0
- package/dist/bridges/forms.d.ts +76 -0
- package/dist/bridges/scene.d.cts +54 -0
- package/dist/bridges/scene.d.ts +54 -0
- package/dist/bridges/sheets.d.cts +62 -0
- package/dist/bridges/sheets.d.ts +62 -0
- package/dist/bridges/whiteboard.d.cts +3 -2
- package/dist/bridges/whiteboard.d.ts +3 -2
- package/dist/bridges-charts.cjs +167 -0
- package/dist/bridges-charts.cjs.map +1 -0
- package/dist/bridges-charts.js +6 -0
- package/dist/bridges-charts.js.map +1 -0
- package/dist/bridges-code.cjs +219 -0
- package/dist/bridges-code.cjs.map +1 -0
- package/dist/bridges-code.js +6 -0
- package/dist/bridges-code.js.map +1 -0
- package/dist/bridges-flow.cjs +76 -17
- package/dist/bridges-flow.cjs.map +1 -1
- package/dist/bridges-flow.js +3 -1
- package/dist/bridges-forms.cjs +205 -0
- package/dist/bridges-forms.cjs.map +1 -0
- package/dist/bridges-forms.js +6 -0
- package/dist/bridges-forms.js.map +1 -0
- package/dist/bridges-scene.cjs +250 -0
- package/dist/bridges-scene.cjs.map +1 -0
- package/dist/bridges-scene.js +6 -0
- package/dist/bridges-scene.js.map +1 -0
- package/dist/bridges-sheets.cjs +327 -0
- package/dist/bridges-sheets.cjs.map +1 -0
- package/dist/bridges-sheets.js +6 -0
- package/dist/bridges-sheets.js.map +1 -0
- package/dist/bridges-whiteboard.cjs +224 -38
- package/dist/bridges-whiteboard.cjs.map +1 -1
- package/dist/bridges-whiteboard.js +4 -1
- package/dist/{chunk-2VOQJKSU.js → chunk-4IAVAFUV.js} +41 -19
- package/dist/chunk-4IAVAFUV.js.map +1 -0
- package/dist/chunk-52S7XYZK.js +38 -0
- package/dist/chunk-52S7XYZK.js.map +1 -0
- package/dist/chunk-ACBENYYO.js +124 -0
- package/dist/chunk-ACBENYYO.js.map +1 -0
- package/dist/chunk-DJOWMF6Q.js +25 -0
- package/dist/chunk-DJOWMF6Q.js.map +1 -0
- package/dist/{chunk-FLEOQUKF.js → chunk-JMYPUAFH.js} +17 -2
- package/dist/chunk-JMYPUAFH.js.map +1 -0
- package/dist/chunk-JU2N4KK6.js +34 -0
- package/dist/chunk-JU2N4KK6.js.map +1 -0
- package/dist/chunk-OEIULP2L.js +158 -0
- package/dist/chunk-OEIULP2L.js.map +1 -0
- package/dist/chunk-PDBF4W7E.js +280 -0
- package/dist/chunk-PDBF4W7E.js.map +1 -0
- package/dist/chunk-PHPXKSWI.js +120 -0
- package/dist/chunk-PHPXKSWI.js.map +1 -0
- package/dist/chunk-QJUTISFC.js +203 -0
- package/dist/chunk-QJUTISFC.js.map +1 -0
- package/dist/{chunk-5ZUHNNLR.js → chunk-TBEITXF4.js} +79 -41
- package/dist/chunk-TBEITXF4.js.map +1 -0
- package/dist/chunk-X66JWQBB.js +37 -0
- package/dist/chunk-X66JWQBB.js.map +1 -0
- package/dist/chunk-XYYSTJHW.js +172 -0
- package/dist/chunk-XYYSTJHW.js.map +1 -0
- package/dist/index.cjs +1411 -57
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +96 -3
- package/dist/index.d.ts +96 -3
- package/dist/index.js +111 -7
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.d.cts +4 -2
- package/dist/mcp/index.d.ts +4 -2
- package/dist/presence/index.d.cts +136 -0
- package/dist/presence/index.d.ts +136 -0
- package/dist/presence.cjs +107 -0
- package/dist/presence.cjs.map +1 -0
- package/dist/presence.js +5 -0
- package/dist/presence.js.map +1 -0
- package/dist/registry-2DRURS6U.js +3 -0
- package/dist/registry-2DRURS6U.js.map +1 -0
- package/dist/server-BJu_AMH3.d.ts +64 -0
- package/dist/server-si-VvFxI.d.cts +64 -0
- package/dist/sharing/index.d.cts +2 -1
- package/dist/sharing/index.d.ts +2 -1
- package/dist/sharing.cjs +68 -0
- package/dist/sharing.cjs.map +1 -1
- package/dist/sharing.js +1 -1
- package/dist/styles.css +57 -0
- package/dist/styles.css.map +1 -1
- package/dist/{types-DR5AS6Rd.d.cts → types-Bf1ZoGmI.d.cts} +1 -1
- package/dist/{types-CRPA_D0z.d.ts → types-DXKpLuia.d.ts} +1 -1
- package/dist/types-DksGd5Y7.d.cts +112 -0
- package/dist/types-DksGd5Y7.d.ts +112 -0
- package/dist/undo/index.d.cts +69 -0
- package/dist/undo/index.d.ts +69 -0
- package/dist/undo.cjs +163 -0
- package/dist/undo.cjs.map +1 -0
- package/dist/undo.js +5 -0
- package/dist/undo.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-2VOQJKSU.js.map +0 -1
- package/dist/chunk-5ZUHNNLR.js.map +0 -1
- package/dist/chunk-FLEOQUKF.js.map +0 -1
- package/dist/server-Bv985us3.d.cts +0 -173
- package/dist/server-Bv985us3.d.ts +0 -173
|
@@ -10,6 +10,156 @@ function textResult(text, structured) {
|
|
|
10
10
|
function errorResult(text) {
|
|
11
11
|
return { content: [{ type: "text", text }], isError: true };
|
|
12
12
|
}
|
|
13
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
14
|
+
function emitActivity(event) {
|
|
15
|
+
for (const l of listeners) l(event);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// src/presence/wrap-tool-with-activity.ts
|
|
19
|
+
function wrapToolWithActivity(handler, options) {
|
|
20
|
+
return async (args) => {
|
|
21
|
+
const result = await handler(args);
|
|
22
|
+
if (result.isError) return result;
|
|
23
|
+
let target;
|
|
24
|
+
if (options.resolveTarget) {
|
|
25
|
+
target = options.resolveTarget({ toolName: options.toolName, args, result });
|
|
26
|
+
} else {
|
|
27
|
+
target = { kind: options.kind, screenId: options.screenId };
|
|
28
|
+
}
|
|
29
|
+
if (!target) return result;
|
|
30
|
+
emitActivity({
|
|
31
|
+
agentId: options.agent.id,
|
|
32
|
+
agentName: options.agent.name,
|
|
33
|
+
agentColor: options.agent.color,
|
|
34
|
+
target: { ...target, kind: target.kind ?? options.kind, screenId: target.screenId ?? options.screenId },
|
|
35
|
+
action: options.toolName,
|
|
36
|
+
timestamp: Date.now(),
|
|
37
|
+
meta: extractMeta(result),
|
|
38
|
+
ttlMs: options.ttlMs
|
|
39
|
+
});
|
|
40
|
+
return result;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function extractMeta(result) {
|
|
44
|
+
const sc = result.structuredContent;
|
|
45
|
+
if (sc && typeof sc === "object" && !Array.isArray(sc)) {
|
|
46
|
+
return sc;
|
|
47
|
+
}
|
|
48
|
+
return void 0;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// src/undo/undo-stack.ts
|
|
52
|
+
var stacks = /* @__PURE__ */ new Map();
|
|
53
|
+
var CAP = 200;
|
|
54
|
+
function getStack(agentId) {
|
|
55
|
+
let s = stacks.get(agentId);
|
|
56
|
+
if (!s) {
|
|
57
|
+
s = { past: [], future: [] };
|
|
58
|
+
stacks.set(agentId, s);
|
|
59
|
+
}
|
|
60
|
+
return s;
|
|
61
|
+
}
|
|
62
|
+
function pushUndoEntry(agentId, entry) {
|
|
63
|
+
const s = getStack(agentId);
|
|
64
|
+
s.past.push(entry);
|
|
65
|
+
if (s.past.length > CAP) s.past.splice(0, s.past.length - CAP);
|
|
66
|
+
s.future.length = 0;
|
|
67
|
+
}
|
|
68
|
+
async function undoOne(agentId) {
|
|
69
|
+
const s = getStack(agentId);
|
|
70
|
+
const entry = s.past.pop();
|
|
71
|
+
if (!entry) return null;
|
|
72
|
+
await entry.undo();
|
|
73
|
+
s.future.push(entry);
|
|
74
|
+
return entry;
|
|
75
|
+
}
|
|
76
|
+
async function redoOne(agentId) {
|
|
77
|
+
const s = getStack(agentId);
|
|
78
|
+
const entry = s.future.pop();
|
|
79
|
+
if (!entry) return null;
|
|
80
|
+
await entry.redo();
|
|
81
|
+
s.past.push(entry);
|
|
82
|
+
return entry;
|
|
83
|
+
}
|
|
84
|
+
function readHistory(agentId) {
|
|
85
|
+
return getStack(agentId).past.slice();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// src/undo/undo-tools.ts
|
|
89
|
+
var installedServers = /* @__PURE__ */ new WeakSet();
|
|
90
|
+
function ensureUndoToolsRegistered(server, options = {}) {
|
|
91
|
+
if (installedServers.has(server)) return;
|
|
92
|
+
installedServers.add(server);
|
|
93
|
+
registerUndoTools(server, options);
|
|
94
|
+
}
|
|
95
|
+
function registerUndoTools(server, options = {}) {
|
|
96
|
+
const defaultAgent = options.defaultAgentId ?? "agent";
|
|
97
|
+
const disposers = [];
|
|
98
|
+
const agentOf = (args) => typeof args?.agentId === "string" ? args.agentId : defaultAgent;
|
|
99
|
+
disposers.push(
|
|
100
|
+
server.registerTool(
|
|
101
|
+
{
|
|
102
|
+
name: "agent_undo",
|
|
103
|
+
description: "Undo the most recent action on the agent's stack. Optional agentId targets a specific agent.",
|
|
104
|
+
inputSchema: {
|
|
105
|
+
type: "object",
|
|
106
|
+
properties: { agentId: { type: "string" } },
|
|
107
|
+
additionalProperties: false
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
async (args) => {
|
|
111
|
+
const entry = await undoOne(agentOf(args));
|
|
112
|
+
if (!entry) return errorResult("Nothing to undo.");
|
|
113
|
+
return textResult(`Undid: ${entry.label}`, { entry: serialize(entry) });
|
|
114
|
+
}
|
|
115
|
+
)
|
|
116
|
+
);
|
|
117
|
+
disposers.push(
|
|
118
|
+
server.registerTool(
|
|
119
|
+
{
|
|
120
|
+
name: "agent_redo",
|
|
121
|
+
description: "Redo the most recently undone action.",
|
|
122
|
+
inputSchema: {
|
|
123
|
+
type: "object",
|
|
124
|
+
properties: { agentId: { type: "string" } },
|
|
125
|
+
additionalProperties: false
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
async (args) => {
|
|
129
|
+
const entry = await redoOne(agentOf(args));
|
|
130
|
+
if (!entry) return errorResult("Nothing to redo.");
|
|
131
|
+
return textResult(`Redid: ${entry.label}`, { entry: serialize(entry) });
|
|
132
|
+
}
|
|
133
|
+
)
|
|
134
|
+
);
|
|
135
|
+
disposers.push(
|
|
136
|
+
server.registerTool(
|
|
137
|
+
{
|
|
138
|
+
name: "agent_history",
|
|
139
|
+
description: "List the agent's undo stack (oldest first). Useful for understanding what's reversible.",
|
|
140
|
+
inputSchema: {
|
|
141
|
+
type: "object",
|
|
142
|
+
properties: { agentId: { type: "string" } },
|
|
143
|
+
additionalProperties: false
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
async (args) => {
|
|
147
|
+
const history2 = readHistory(agentOf(args)).map(serialize);
|
|
148
|
+
const text = history2.map((e) => `${new Date(e.timestamp).toISOString()} ${e.bridgeId} ${e.action}: ${e.label}`).join("\n");
|
|
149
|
+
return textResult(text || "(empty)", history2);
|
|
150
|
+
}
|
|
151
|
+
)
|
|
152
|
+
);
|
|
153
|
+
return () => disposers.forEach((d) => d());
|
|
154
|
+
}
|
|
155
|
+
function serialize(entry) {
|
|
156
|
+
return {
|
|
157
|
+
timestamp: entry.timestamp,
|
|
158
|
+
bridgeId: entry.bridgeId,
|
|
159
|
+
action: entry.action,
|
|
160
|
+
label: entry.label
|
|
161
|
+
};
|
|
162
|
+
}
|
|
13
163
|
|
|
14
164
|
// src/bridges/whiteboard.ts
|
|
15
165
|
var DEFAULT_AGENT = { id: "agent", name: "Agent", color: "#a855f7" };
|
|
@@ -22,7 +172,25 @@ function registerWhiteboardBridge(server, options) {
|
|
|
22
172
|
const { adapter } = options;
|
|
23
173
|
const agent = { ...DEFAULT_AGENT, ...options.agent ?? {} };
|
|
24
174
|
const disposers = [];
|
|
25
|
-
|
|
175
|
+
ensureUndoToolsRegistered(server, { defaultAgentId: agent.id });
|
|
176
|
+
const wbTarget = (args, result) => ({
|
|
177
|
+
kind: "whiteboard",
|
|
178
|
+
elementId: result?.structuredContent?.id ?? args?.id
|
|
179
|
+
});
|
|
180
|
+
const reg = (name, description, inputProperties, required, handler, resolveTarget) => {
|
|
181
|
+
const wrapped = async (args) => {
|
|
182
|
+
try {
|
|
183
|
+
return await handler(args);
|
|
184
|
+
} catch (e) {
|
|
185
|
+
return errorResult(e instanceof Error ? e.message : String(e));
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
const final = resolveTarget ? wrapToolWithActivity(wrapped, {
|
|
189
|
+
toolName: name,
|
|
190
|
+
agent: { id: agent.id, name: agent.name, color: agent.color },
|
|
191
|
+
kind: "whiteboard",
|
|
192
|
+
resolveTarget: ({ args, result }) => resolveTarget(args, result)
|
|
193
|
+
}) : wrapped;
|
|
26
194
|
disposers.push(
|
|
27
195
|
server.registerTool(
|
|
28
196
|
{
|
|
@@ -35,13 +203,7 @@ function registerWhiteboardBridge(server, options) {
|
|
|
35
203
|
additionalProperties: false
|
|
36
204
|
}
|
|
37
205
|
},
|
|
38
|
-
|
|
39
|
-
try {
|
|
40
|
-
return await handler(args);
|
|
41
|
-
} catch (e) {
|
|
42
|
-
return errorResult(e instanceof Error ? e.message : String(e));
|
|
43
|
-
}
|
|
44
|
-
}
|
|
206
|
+
final
|
|
45
207
|
)
|
|
46
208
|
);
|
|
47
209
|
};
|
|
@@ -118,8 +280,17 @@ function registerWhiteboardBridge(server, options) {
|
|
|
118
280
|
authorId: agent.id
|
|
119
281
|
};
|
|
120
282
|
adapter.setNotes((all) => [...all, note]);
|
|
283
|
+
pushUndoEntry(agent.id, {
|
|
284
|
+
timestamp: Date.now(),
|
|
285
|
+
bridgeId: "whiteboard",
|
|
286
|
+
action: "whiteboard_add_sticky",
|
|
287
|
+
label: `Added sticky ${note.id}`,
|
|
288
|
+
undo: () => adapter.setNotes((all) => all.filter((n) => n.id !== note.id)),
|
|
289
|
+
redo: () => adapter.setNotes((all) => [...all, note])
|
|
290
|
+
});
|
|
121
291
|
return textResult(`Added sticky ${note.id}`, note);
|
|
122
|
-
}
|
|
292
|
+
},
|
|
293
|
+
wbTarget
|
|
123
294
|
);
|
|
124
295
|
reg(
|
|
125
296
|
"whiteboard_stream_text",
|
|
@@ -186,7 +357,8 @@ function registerWhiteboardBridge(server, options) {
|
|
|
186
357
|
})
|
|
187
358
|
);
|
|
188
359
|
return textResult(`Updated sticky ${id}`, updated);
|
|
189
|
-
}
|
|
360
|
+
},
|
|
361
|
+
wbTarget
|
|
190
362
|
);
|
|
191
363
|
reg(
|
|
192
364
|
"whiteboard_add_shape",
|
|
@@ -227,7 +399,8 @@ function registerWhiteboardBridge(server, options) {
|
|
|
227
399
|
};
|
|
228
400
|
adapter.setShapes((all) => [...all, shape]);
|
|
229
401
|
return textResult(`Added ${kind} ${shape.id}`, shape);
|
|
230
|
-
}
|
|
402
|
+
},
|
|
403
|
+
wbTarget
|
|
231
404
|
);
|
|
232
405
|
reg(
|
|
233
406
|
"whiteboard_update_shape",
|
|
@@ -269,7 +442,8 @@ function registerWhiteboardBridge(server, options) {
|
|
|
269
442
|
})
|
|
270
443
|
);
|
|
271
444
|
return textResult(`Updated shape ${id}`, updated);
|
|
272
|
-
}
|
|
445
|
+
},
|
|
446
|
+
wbTarget
|
|
273
447
|
);
|
|
274
448
|
reg(
|
|
275
449
|
"whiteboard_add_connector",
|
|
@@ -290,7 +464,8 @@ function registerWhiteboardBridge(server, options) {
|
|
|
290
464
|
};
|
|
291
465
|
adapter.setConnectors((all) => [...all, c]);
|
|
292
466
|
return textResult(`Added connector ${c.id}`, c);
|
|
293
|
-
}
|
|
467
|
+
},
|
|
468
|
+
wbTarget
|
|
294
469
|
);
|
|
295
470
|
reg(
|
|
296
471
|
"whiteboard_add_stroke",
|
|
@@ -319,7 +494,8 @@ function registerWhiteboardBridge(server, options) {
|
|
|
319
494
|
};
|
|
320
495
|
adapter.setStrokes((all) => [...all, stroke]);
|
|
321
496
|
return textResult(`Added stroke ${stroke.id} (${points.length} points)`, stroke);
|
|
322
|
-
}
|
|
497
|
+
},
|
|
498
|
+
wbTarget
|
|
323
499
|
);
|
|
324
500
|
reg(
|
|
325
501
|
"whiteboard_delete_item",
|
|
@@ -328,29 +504,37 @@ function registerWhiteboardBridge(server, options) {
|
|
|
328
504
|
["id"],
|
|
329
505
|
(args) => {
|
|
330
506
|
const id = str(args.id);
|
|
331
|
-
|
|
332
|
-
adapter.
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
});
|
|
337
|
-
adapter.
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
507
|
+
const removedNotes = adapter.getNotes().filter((x) => x.id === id);
|
|
508
|
+
const removedShapes = adapter.getShapes().filter((x) => x.id === id);
|
|
509
|
+
const removedConnectors = adapter.getConnectors().filter((x) => x.id === id);
|
|
510
|
+
const removedStrokes = adapter.getStrokes().filter((x) => x.id === id);
|
|
511
|
+
const removed = removedNotes.length + removedShapes.length + removedConnectors.length + removedStrokes.length > 0;
|
|
512
|
+
if (!removed) return errorResult(`No item with id ${id}`);
|
|
513
|
+
adapter.setNotes((all) => all.filter((x) => x.id !== id));
|
|
514
|
+
adapter.setShapes((all) => all.filter((x) => x.id !== id));
|
|
515
|
+
adapter.setConnectors((all) => all.filter((x) => x.id !== id));
|
|
516
|
+
adapter.setStrokes((all) => all.filter((x) => x.id !== id));
|
|
517
|
+
pushUndoEntry(agent.id, {
|
|
518
|
+
timestamp: Date.now(),
|
|
519
|
+
bridgeId: "whiteboard",
|
|
520
|
+
action: "whiteboard_delete_item",
|
|
521
|
+
label: `Deleted ${id}`,
|
|
522
|
+
undo: () => {
|
|
523
|
+
if (removedNotes.length) adapter.setNotes((all) => [...all, ...removedNotes]);
|
|
524
|
+
if (removedShapes.length) adapter.setShapes((all) => [...all, ...removedShapes]);
|
|
525
|
+
if (removedConnectors.length) adapter.setConnectors((all) => [...all, ...removedConnectors]);
|
|
526
|
+
if (removedStrokes.length) adapter.setStrokes((all) => [...all, ...removedStrokes]);
|
|
527
|
+
},
|
|
528
|
+
redo: () => {
|
|
529
|
+
adapter.setNotes((all) => all.filter((x) => x.id !== id));
|
|
530
|
+
adapter.setShapes((all) => all.filter((x) => x.id !== id));
|
|
531
|
+
adapter.setConnectors((all) => all.filter((x) => x.id !== id));
|
|
532
|
+
adapter.setStrokes((all) => all.filter((x) => x.id !== id));
|
|
533
|
+
}
|
|
351
534
|
});
|
|
352
|
-
return
|
|
353
|
-
}
|
|
535
|
+
return textResult(`Deleted ${id}`);
|
|
536
|
+
},
|
|
537
|
+
wbTarget
|
|
354
538
|
);
|
|
355
539
|
reg(
|
|
356
540
|
"whiteboard_set_viewport",
|
|
@@ -366,7 +550,8 @@ function registerWhiteboardBridge(server, options) {
|
|
|
366
550
|
};
|
|
367
551
|
adapter.setViewport(next);
|
|
368
552
|
return textResult(`Viewport \u2192 ${JSON.stringify(next)}`, next);
|
|
369
|
-
}
|
|
553
|
+
},
|
|
554
|
+
wbTarget
|
|
370
555
|
);
|
|
371
556
|
reg(
|
|
372
557
|
"whiteboard_set_agent_cursor",
|
|
@@ -392,7 +577,8 @@ function registerWhiteboardBridge(server, options) {
|
|
|
392
577
|
};
|
|
393
578
|
adapter.setAgentCursor(cursor);
|
|
394
579
|
return textResult(`Cursor \u2192 (${cursor.x}, ${cursor.y})`, cursor);
|
|
395
|
-
}
|
|
580
|
+
},
|
|
581
|
+
wbTarget
|
|
396
582
|
);
|
|
397
583
|
return {
|
|
398
584
|
id: "whiteboard",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/mcp/server.ts","../src/bridges/whiteboard.ts"],"names":[],"mappings":"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","file":"bridges-whiteboard.cjs","sourcesContent":["import {\n type CallToolResult,\n type JsonObject,\n type JsonRpcMessage,\n type JsonRpcRequest,\n type JsonRpcId,\n type RegisteredTool,\n type ServerCapabilities,\n type ServerInfo,\n type ToolDefinition,\n type ToolHandler,\n JSONRPC_INTERNAL_ERROR,\n JSONRPC_INVALID_PARAMS,\n JSONRPC_METHOD_NOT_FOUND,\n MCP_PROTOCOL_VERSION,\n} from \"./types\";\n\nexport type McpServerOptions = {\n info: ServerInfo;\n /** Defaults to { tools: { listChanged: true } } */\n capabilities?: ServerCapabilities;\n /** Free-text instructions surfaced to clients during initialize. */\n instructions?: string;\n};\n\nexport type Transport = {\n /** Called by the server when it has a message to deliver to the client. */\n send: (message: JsonRpcMessage) => void;\n /** Called by the server when it's torn down so the transport can clean up. */\n close?: () => void;\n};\n\n/**\n * MicroMcpServer — protocol-level MCP server, transport-agnostic.\n *\n * Use it like:\n *\n * const server = new MicroMcpServer({ info: { name: \"session\", version: \"0.1\" } });\n * server.registerTool({ name: \"...\", inputSchema: { type: \"object\" } }, async (args) => ({...}));\n * const transport = new InProcessTransport();\n * server.attach(transport);\n * transport.deliver({ ... }); // client → server frames\n *\n * The same server can serve multiple transports (e.g. an in-process agent\n * AND a relayed external client) by attaching each one.\n */\nexport class MicroMcpServer {\n private tools = new Map<string, RegisteredTool>();\n private transports = new Set<Transport>();\n private notifyListChangedScheduled = false;\n\n readonly info: ServerInfo;\n readonly capabilities: ServerCapabilities;\n readonly instructions?: string;\n\n constructor(options: McpServerOptions) {\n this.info = options.info;\n this.capabilities = options.capabilities ?? { tools: { listChanged: true } };\n this.instructions = options.instructions;\n }\n\n attach(transport: Transport): () => void {\n this.transports.add(transport);\n return () => this.detach(transport);\n }\n\n detach(transport: Transport): void {\n if (this.transports.delete(transport)) {\n transport.close?.();\n }\n }\n\n registerTool(definition: ToolDefinition, handler: ToolHandler): () => void {\n this.tools.set(definition.name, { definition, handler });\n this.scheduleListChangedNotification();\n return () => this.unregisterTool(definition.name);\n }\n\n unregisterTool(name: string): void {\n if (this.tools.delete(name)) {\n this.scheduleListChangedNotification();\n }\n }\n\n listTools(): ToolDefinition[] {\n return Array.from(this.tools.values()).map((t) => t.definition);\n }\n\n /**\n * Receive a JSON-RPC frame from a client (called by the transport).\n * The transport is responsible for sending the response back.\n */\n async receive(transport: Transport, message: JsonRpcMessage): Promise<void> {\n if (!(\"method\" in message)) return; // It's a response, not a request — ignore.\n\n const isNotification = !(\"id\" in message);\n if (isNotification) {\n // Notifications are fire-and-forget. We ignore unknown methods.\n return;\n }\n\n const request = message as JsonRpcRequest;\n try {\n const result = await this.handle(request);\n transport.send({ jsonrpc: \"2.0\", id: request.id, result });\n } catch (err) {\n transport.send({\n jsonrpc: \"2.0\",\n id: request.id,\n error: this.toRpcError(err),\n });\n }\n }\n\n private async handle(request: JsonRpcRequest): Promise<any> {\n const { method, params } = request;\n switch (method) {\n case \"initialize\":\n return {\n protocolVersion: MCP_PROTOCOL_VERSION,\n capabilities: this.capabilities,\n serverInfo: this.info,\n ...(this.instructions ? { instructions: this.instructions } : {}),\n };\n\n case \"tools/list\":\n return { tools: this.listTools() };\n\n case \"tools/call\": {\n const name = params?.name;\n const args = (params?.arguments ?? {}) as JsonObject;\n if (typeof name !== \"string\") {\n throw rpcError(JSONRPC_INVALID_PARAMS, \"tools/call requires `name`\");\n }\n const tool = this.tools.get(name);\n if (!tool) {\n throw rpcError(JSONRPC_METHOD_NOT_FOUND, `Unknown tool: ${name}`);\n }\n const result = await tool.handler(args);\n return result satisfies CallToolResult;\n }\n\n case \"ping\":\n return {};\n\n default:\n throw rpcError(JSONRPC_METHOD_NOT_FOUND, `Unsupported method: ${method}`);\n }\n }\n\n private scheduleListChangedNotification(): void {\n if (this.notifyListChangedScheduled) return;\n this.notifyListChangedScheduled = true;\n queueMicrotask(() => {\n this.notifyListChangedScheduled = false;\n this.broadcast({ jsonrpc: \"2.0\", method: \"notifications/tools/list_changed\" });\n });\n }\n\n private broadcast(message: JsonRpcMessage): void {\n for (const t of this.transports) t.send(message);\n }\n\n private toRpcError(err: unknown): { code: number; message: string; data?: any } {\n if (err && typeof err === \"object\" && \"code\" in err && \"message\" in err) {\n return err as any;\n }\n return {\n code: JSONRPC_INTERNAL_ERROR,\n message: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\nexport function rpcError(code: number, message: string, data?: any) {\n return { code, message, ...(data !== undefined ? { data } : {}) };\n}\n\n/**\n * Helper to build a CallToolResult from a string or structured value.\n */\nexport function textResult(text: string, structured?: any): CallToolResult {\n return {\n content: [{ type: \"text\", text }],\n ...(structured !== undefined ? { structuredContent: structured } : {}),\n };\n}\n\nexport function errorResult(text: string): CallToolResult {\n return { content: [{ type: \"text\", text }], isError: true };\n}\n\n// Internal helper so the JsonRpcId import isn't dropped by tsup\ntype _KeepIdImport = JsonRpcId;\n","import type {\n BoardItem,\n ConnectorItem,\n RemoteCursor,\n ShapeItem,\n ShapeKind,\n StickyNoteItem,\n Stroke,\n Viewport,\n} from \"@particle-academy/fancy-whiteboard\";\nimport { textResult, errorResult } from \"../mcp/server\";\nimport type { MicroMcpServer } from \"../mcp/server\";\nimport type { JsonObject } from \"../mcp/types\";\nimport type { Bridge } from \"./types\";\n\n/**\n * State accessors / mutators the bridge needs from the host. The host owns\n * whiteboard state (controlled props on fancy-whiteboard components); the\n * bridge calls into these to read or change it.\n */\nexport type WhiteboardBridgeAdapter = {\n getNotes: () => StickyNoteItem[];\n setNotes: (next: StickyNoteItem[] | ((prev: StickyNoteItem[]) => StickyNoteItem[])) => void;\n getShapes: () => ShapeItem[];\n setShapes: (next: ShapeItem[] | ((prev: ShapeItem[]) => ShapeItem[])) => void;\n getConnectors: () => ConnectorItem[];\n setConnectors: (next: ConnectorItem[] | ((prev: ConnectorItem[]) => ConnectorItem[])) => void;\n getStrokes: () => Stroke[];\n setStrokes: (next: Stroke[] | ((prev: Stroke[]) => Stroke[])) => void;\n getViewport: () => Viewport;\n setViewport: (next: Viewport) => void;\n /** Optional: agent presence cursor (for the visualizer). */\n setAgentCursor?: (cursor: RemoteCursor | null) => void;\n};\n\nexport type WhiteboardBridgeOptions = {\n adapter: WhiteboardBridgeAdapter;\n /** Identity used when the agent stamps authorId on items / cursor. */\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\nconst VALID_SHAPES: ShapeKind[] = [\"rect\", \"rounded-rect\", \"ellipse\", \"diamond\", \"triangle\", \"line\", \"arrow\", \"text\"];\n\nconst num = (v: unknown, fallback?: number): number =>\n typeof v === \"number\" && Number.isFinite(v) ? v : fallback ?? 0;\nconst str = (v: unknown, fallback = \"\"): string => (typeof v === \"string\" ? v : fallback);\nconst bool = (v: unknown, fallback = false): boolean => (typeof v === \"boolean\" ? v : fallback);\n\nconst newId = (prefix: string) =>\n `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`;\n\n/**\n * registerWhiteboardBridge — wires a full MCP tool set against a fancy-\n * whiteboard session controlled by the host. Returns a Bridge handle the\n * host can dispose to tear everything down.\n */\nexport function registerWhiteboardBridge(\n server: MicroMcpServer,\n options: WhiteboardBridgeOptions,\n): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n\n // Cursor narration is the agent's responsibility — call\n // whiteboard_set_agent_cursor as a separate prerequisite before any\n // mutation. This keeps the protocol honest: each tool does one thing.\n\n\n const reg = (\n name: string,\n description: string,\n inputProperties: Record<string, unknown>,\n required: string[],\n handler: (args: JsonObject) => Promise<any> | any,\n ) => {\n disposers.push(\n server.registerTool(\n {\n name,\n description,\n inputSchema: {\n type: \"object\",\n properties: inputProperties as any,\n required,\n additionalProperties: false,\n },\n },\n async (args) => {\n try {\n return await handler(args);\n } catch (e) {\n return errorResult(e instanceof Error ? e.message : String(e));\n }\n },\n ),\n );\n };\n\n // ───────────── Read tools ─────────────\n\n reg(\"whiteboard_get_state\", \"Get the full board state: viewport, all items, strokes.\", {}, [], () => {\n const state = {\n viewport: adapter.getViewport(),\n notes: adapter.getNotes(),\n shapes: adapter.getShapes(),\n connectors: adapter.getConnectors(),\n strokes: adapter.getStrokes(),\n };\n return textResult(JSON.stringify(state, null, 2), state);\n });\n\n reg(\"whiteboard_list_items\", \"List notes, shapes, and connectors with id, kind, and bounds.\", {}, [], () => {\n const items: Array<{ id: string; kind: string; summary: string }> = [];\n for (const n of adapter.getNotes()) {\n items.push({\n id: n.id,\n kind: \"sticky\",\n summary: `\"${(n.text ?? \"\").slice(0, 40)}\" @(${Math.round(n.x)},${Math.round(n.y)}) ${n.width}×${n.height}`,\n });\n }\n for (const s of adapter.getShapes()) {\n items.push({\n id: s.id,\n kind: `shape:${s.shape}`,\n summary: `${s.text ? `\"${s.text}\" ` : \"\"}@(${Math.round(s.x)},${Math.round(s.y)}) ${s.width}×${s.height}`,\n });\n }\n for (const c of adapter.getConnectors()) {\n items.push({ id: c.id, kind: \"connector\", summary: `from=${JSON.stringify(c.from)} to=${JSON.stringify(c.to)}` });\n }\n return textResult(items.map((i) => `${i.kind} ${i.id}: ${i.summary}`).join(\"\\n\") || \"(empty board)\", items);\n });\n\n reg(\n \"whiteboard_get_item\",\n \"Get a single item (sticky / shape / connector) by id.\",\n { id: { type: \"string\" } },\n [\"id\"],\n (args) => {\n const id = str(args.id);\n const all: BoardItem[] = [...adapter.getNotes(), ...adapter.getShapes(), ...adapter.getConnectors()];\n const found = all.find((x) => x.id === id);\n if (!found) return errorResult(`No item with id ${id}`);\n return textResult(JSON.stringify(found, null, 2), found);\n },\n );\n\n // ───────────── Sticky CRUD ─────────────\n\n reg(\n \"whiteboard_add_sticky\",\n \"Add a sticky note. Position is in world coordinates.\",\n {\n x: { type: \"number\" },\n y: { type: \"number\" },\n text: { type: \"string\" },\n width: { type: \"number\" },\n height: { type: \"number\" },\n color: { type: \"string\", description: \"CSS color, e.g. #fde68a\" },\n },\n [\"x\", \"y\"],\n async (args) => {\n const x = num(args.x);\n const y = num(args.y);\n const width = num(args.width, 180);\n const height = num(args.height, 140);\n// (cursor narration is now an explicit separate tool call)\n const note: StickyNoteItem = {\n id: newId(\"n\"),\n kind: \"sticky\",\n x, y, width, height,\n text: str(args.text),\n color: typeof args.color === \"string\" ? args.color : \"#fde68a\",\n authorId: agent.id,\n };\n adapter.setNotes((all) => [...all, note]);\n return textResult(`Added sticky ${note.id}`, note);\n },\n );\n\n reg(\n \"whiteboard_stream_text\",\n \"Type text into a sticky note character-by-character so the human can read it forming. The tool returns once streaming finishes.\",\n {\n id: { type: \"string\" },\n text: { type: \"string\" },\n cps: { type: \"number\", description: \"Characters per second. Default 25.\" },\n append: { type: \"boolean\", description: \"Append to existing text instead of replacing. Default false.\" },\n },\n [\"id\", \"text\"],\n async (args) => {\n const id = str(args.id);\n const target = str(args.text);\n const cps = Math.max(1, num(args.cps, 25));\n const append = bool(args.append);\n const startNote = adapter.getNotes().find((n) => n.id === id);\n if (!startNote) return errorResult(`No sticky with id ${id}`);\n const base = append ? (startNote.text ?? \"\") : \"\";\n const interval = Math.max(8, Math.round(1000 / cps));\n for (let i = 0; i <= target.length; i++) {\n const nextText = base + target.slice(0, i);\n adapter.setNotes((all) => all.map((n) => (n.id === id ? { ...n, text: nextText } : n)));\n if (i < target.length) await new Promise((r) => setTimeout(r, interval));\n }\n return textResult(`Streamed ${target.length} chars to ${id}`, { id, text: base + target });\n },\n );\n\n reg(\n \"whiteboard_update_sticky\",\n \"Update fields on a sticky note. Only provided fields are changed.\",\n {\n id: { type: \"string\" },\n x: { type: \"number\" },\n y: { type: \"number\" },\n width: { type: \"number\" },\n height: { type: \"number\" },\n text: { type: \"string\" },\n color: { type: \"string\" },\n },\n [\"id\"],\n async (args) => {\n const id = str(args.id);\n const existing = adapter.getNotes().find((n) => n.id === id);\n if (!existing) return errorResult(`No sticky with id ${id}`);\n const nextX = args.x !== undefined ? num(args.x) : existing.x;\n const nextY = args.y !== undefined ? num(args.y) : existing.y;\n const nextW = args.width !== undefined ? num(args.width) : existing.width;\n const nextH = args.height !== undefined ? num(args.height) : existing.height;\n// (cursor narration is now an explicit separate tool call)\n let updated: StickyNoteItem | null = null;\n adapter.setNotes((all) =>\n all.map((n) => {\n if (n.id !== id) return n;\n updated = {\n ...n,\n x: nextX, y: nextY, width: nextW, height: nextH,\n ...(args.text !== undefined ? { text: str(args.text) } : {}),\n ...(args.color !== undefined ? { color: str(args.color) } : {}),\n };\n return updated;\n }),\n );\n return textResult(`Updated sticky ${id}`, updated);\n },\n );\n\n // ───────────── Shape CRUD ─────────────\n\n reg(\n \"whiteboard_add_shape\",\n `Add a shape. Kind must be one of: ${VALID_SHAPES.join(\", \")}.`,\n {\n shape: { type: \"string\", enum: VALID_SHAPES },\n x: { type: \"number\" },\n y: { type: \"number\" },\n width: { type: \"number\" },\n height: { type: \"number\" },\n text: { type: \"string\" },\n fill: { type: \"string\" },\n stroke: { type: \"string\" },\n flipX: { type: \"boolean\" },\n flipY: { type: \"boolean\" },\n },\n [\"shape\", \"x\", \"y\", \"width\", \"height\"],\n async (args) => {\n const kind = str(args.shape) as ShapeKind;\n if (!VALID_SHAPES.includes(kind)) return errorResult(`Invalid shape kind: ${kind}`);\n const x = num(args.x);\n const y = num(args.y);\n const width = num(args.width);\n const height = num(args.height);\n// (cursor narration is now an explicit separate tool call)\n const shape: ShapeItem = {\n id: newId(\"s\"),\n kind: \"shape\",\n shape: kind,\n x, y, width, height,\n ...(args.text !== undefined ? { text: str(args.text) } : {}),\n ...(args.fill !== undefined ? { fill: str(args.fill) } : {}),\n ...(args.stroke !== undefined ? { stroke: str(args.stroke) } : {}),\n ...(args.flipX !== undefined ? { flipX: bool(args.flipX) } : {}),\n ...(args.flipY !== undefined ? { flipY: bool(args.flipY) } : {}),\n };\n adapter.setShapes((all) => [...all, shape]);\n return textResult(`Added ${kind} ${shape.id}`, shape);\n },\n );\n\n reg(\n \"whiteboard_update_shape\",\n \"Update fields on a shape.\",\n {\n id: { type: \"string\" },\n x: { type: \"number\" },\n y: { type: \"number\" },\n width: { type: \"number\" },\n height: { type: \"number\" },\n text: { type: \"string\" },\n fill: { type: \"string\" },\n stroke: { type: \"string\" },\n },\n [\"id\"],\n async (args) => {\n const id = str(args.id);\n const existing = adapter.getShapes().find((s) => s.id === id);\n if (!existing) return errorResult(`No shape with id ${id}`);\n const nextX = args.x !== undefined ? num(args.x) : existing.x;\n const nextY = args.y !== undefined ? num(args.y) : existing.y;\n const nextW = args.width !== undefined ? num(args.width) : existing.width;\n const nextH = args.height !== undefined ? num(args.height) : existing.height;\n// (cursor narration is now an explicit separate tool call)\n let updated: ShapeItem | null = null;\n adapter.setShapes((all) =>\n all.map((s) => {\n if (s.id !== id) return s;\n updated = {\n ...s,\n x: nextX, y: nextY, width: nextW, height: nextH,\n ...(args.text !== undefined ? { text: str(args.text) } : {}),\n ...(args.fill !== undefined ? { fill: str(args.fill) } : {}),\n ...(args.stroke !== undefined ? { stroke: str(args.stroke) } : {}),\n };\n return updated;\n }),\n );\n return textResult(`Updated shape ${id}`, updated);\n },\n );\n\n // ───────────── Connectors ─────────────\n\n reg(\n \"whiteboard_add_connector\",\n \"Connect two items by id, or specify explicit world-space points.\",\n {\n from: { description: \"Item id (string) or {x,y}\" },\n to: { description: \"Item id (string) or {x,y}\" },\n color: { type: \"string\" },\n },\n [\"from\", \"to\"],\n (args) => {\n const c: ConnectorItem = {\n id: newId(\"c\"),\n kind: \"connector\",\n from: args.from as any,\n to: args.to as any,\n ...(args.color !== undefined ? { color: str(args.color) } : {}),\n };\n adapter.setConnectors((all) => [...all, c]);\n return textResult(`Added connector ${c.id}`, c);\n },\n );\n\n // ───────────── Drawing ─────────────\n\n reg(\n \"whiteboard_add_stroke\",\n \"Add a freeform pen stroke. Points are absolute screen coords (matching the Drawing layer).\",\n {\n points: {\n type: \"array\",\n description: \"Array of {x,y} points\",\n },\n color: { type: \"string\" },\n size: { type: \"number\" },\n },\n [\"points\"],\n (args) => {\n const points = (Array.isArray(args.points) ? args.points : []).map((p: any) => ({\n x: num(p?.x),\n y: num(p?.y),\n }));\n if (!points.length) return errorResult(\"Stroke requires at least one point\");\n const stroke: Stroke = {\n id: newId(\"st\"),\n points,\n color: typeof args.color === \"string\" ? args.color : \"#0f172a\",\n size: typeof args.size === \"number\" ? args.size : 2,\n authorId: agent.id,\n };\n adapter.setStrokes((all) => [...all, stroke]);\n return textResult(`Added stroke ${stroke.id} (${points.length} points)`, stroke);\n },\n );\n\n // ───────────── Generic delete ─────────────\n\n reg(\n \"whiteboard_delete_item\",\n \"Remove any item by id (sticky / shape / connector / stroke).\",\n { id: { type: \"string\" } },\n [\"id\"],\n (args) => {\n const id = str(args.id);\n let removed = false;\n adapter.setNotes((all) => {\n const next = all.filter((x) => x.id !== id);\n if (next.length !== all.length) removed = true;\n return next;\n });\n adapter.setShapes((all) => {\n const next = all.filter((x) => x.id !== id);\n if (next.length !== all.length) removed = true;\n return next;\n });\n adapter.setConnectors((all) => {\n const next = all.filter((x) => x.id !== id);\n if (next.length !== all.length) removed = true;\n return next;\n });\n adapter.setStrokes((all) => {\n const next = all.filter((x) => x.id !== id);\n if (next.length !== all.length) removed = true;\n return next;\n });\n return removed ? textResult(`Deleted ${id}`) : errorResult(`No item with id ${id}`);\n },\n );\n\n // ───────────── Viewport / agent presence ─────────────\n\n reg(\n \"whiteboard_set_viewport\",\n \"Pan / zoom the viewport.\",\n { x: { type: \"number\" }, y: { type: \"number\" }, zoom: { type: \"number\" } },\n [],\n (args) => {\n const v = adapter.getViewport();\n const next: Viewport = {\n x: args.x !== undefined ? num(args.x) : v.x,\n y: args.y !== undefined ? num(args.y) : v.y,\n zoom: args.zoom !== undefined ? num(args.zoom) : v.zoom,\n };\n adapter.setViewport(next);\n return textResult(`Viewport → ${JSON.stringify(next)}`, next);\n },\n );\n\n reg(\n \"whiteboard_set_agent_cursor\",\n \"Move the agent's presence cursor (or pass null to hide it).\",\n {\n x: { type: \"number\" },\n y: { type: \"number\" },\n hide: { type: \"boolean\" },\n },\n [],\n (args) => {\n if (!adapter.setAgentCursor) return errorResult(\"Host did not provide setAgentCursor\");\n if (bool(args.hide)) {\n adapter.setAgentCursor(null);\n return textResult(\"Agent cursor hidden\");\n }\n const cursor: RemoteCursor = {\n userId: agent.id,\n name: agent.name,\n color: agent.color,\n x: num(args.x),\n y: num(args.y),\n };\n adapter.setAgentCursor(cursor);\n return textResult(`Cursor → (${cursor.x}, ${cursor.y})`, cursor);\n },\n );\n\n return {\n id: \"whiteboard\",\n title: \"Whiteboard\",\n dispose: () => {\n for (const d of disposers) d();\n adapter.setAgentCursor?.(null);\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/mcp/server.ts","../src/presence/registry.ts","../src/presence/wrap-tool-with-activity.ts","../src/undo/undo-stack.ts","../src/undo/undo-tools.ts","../src/bridges/whiteboard.ts"],"names":["history"],"mappings":"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","file":"bridges-whiteboard.cjs","sourcesContent":["import {\n type CallToolResult,\n type JsonObject,\n type JsonRpcMessage,\n type JsonRpcRequest,\n type JsonRpcId,\n type RegisteredTool,\n type ServerCapabilities,\n type ServerInfo,\n type ToolDefinition,\n type ToolHandler,\n JSONRPC_INTERNAL_ERROR,\n JSONRPC_INVALID_PARAMS,\n JSONRPC_METHOD_NOT_FOUND,\n MCP_PROTOCOL_VERSION,\n} from \"./types\";\n\nexport type McpServerOptions = {\n info: ServerInfo;\n /** Defaults to { tools: { listChanged: true } } */\n capabilities?: ServerCapabilities;\n /** Free-text instructions surfaced to clients during initialize. */\n instructions?: string;\n};\n\nexport type Transport = {\n /** Called by the server when it has a message to deliver to the client. */\n send: (message: JsonRpcMessage) => void;\n /** Called by the server when it's torn down so the transport can clean up. */\n close?: () => void;\n};\n\n/**\n * MicroMcpServer — protocol-level MCP server, transport-agnostic.\n *\n * Use it like:\n *\n * const server = new MicroMcpServer({ info: { name: \"session\", version: \"0.1\" } });\n * server.registerTool({ name: \"...\", inputSchema: { type: \"object\" } }, async (args) => ({...}));\n * const transport = new InProcessTransport();\n * server.attach(transport);\n * transport.deliver({ ... }); // client → server frames\n *\n * The same server can serve multiple transports (e.g. an in-process agent\n * AND a relayed external client) by attaching each one.\n */\nexport class MicroMcpServer {\n private tools = new Map<string, RegisteredTool>();\n private transports = new Set<Transport>();\n private notifyListChangedScheduled = false;\n\n readonly info: ServerInfo;\n readonly capabilities: ServerCapabilities;\n readonly instructions?: string;\n\n constructor(options: McpServerOptions) {\n this.info = options.info;\n this.capabilities = options.capabilities ?? { tools: { listChanged: true } };\n this.instructions = options.instructions;\n }\n\n attach(transport: Transport): () => void {\n this.transports.add(transport);\n return () => this.detach(transport);\n }\n\n detach(transport: Transport): void {\n if (this.transports.delete(transport)) {\n transport.close?.();\n }\n }\n\n registerTool(definition: ToolDefinition, handler: ToolHandler): () => void {\n this.tools.set(definition.name, { definition, handler });\n this.scheduleListChangedNotification();\n return () => this.unregisterTool(definition.name);\n }\n\n unregisterTool(name: string): void {\n if (this.tools.delete(name)) {\n this.scheduleListChangedNotification();\n }\n }\n\n listTools(): ToolDefinition[] {\n return Array.from(this.tools.values()).map((t) => t.definition);\n }\n\n /**\n * Receive a JSON-RPC frame from a client (called by the transport).\n * The transport is responsible for sending the response back.\n */\n async receive(transport: Transport, message: JsonRpcMessage): Promise<void> {\n if (!(\"method\" in message)) return; // It's a response, not a request — ignore.\n\n const isNotification = !(\"id\" in message);\n if (isNotification) {\n // Notifications are fire-and-forget. We ignore unknown methods.\n return;\n }\n\n const request = message as JsonRpcRequest;\n try {\n const result = await this.handle(request);\n transport.send({ jsonrpc: \"2.0\", id: request.id, result });\n } catch (err) {\n transport.send({\n jsonrpc: \"2.0\",\n id: request.id,\n error: this.toRpcError(err),\n });\n }\n }\n\n private async handle(request: JsonRpcRequest): Promise<any> {\n const { method, params } = request;\n switch (method) {\n case \"initialize\":\n return {\n protocolVersion: MCP_PROTOCOL_VERSION,\n capabilities: this.capabilities,\n serverInfo: this.info,\n ...(this.instructions ? { instructions: this.instructions } : {}),\n };\n\n case \"tools/list\":\n return { tools: this.listTools() };\n\n case \"tools/call\": {\n const name = params?.name;\n const args = (params?.arguments ?? {}) as JsonObject;\n if (typeof name !== \"string\") {\n throw rpcError(JSONRPC_INVALID_PARAMS, \"tools/call requires `name`\");\n }\n const tool = this.tools.get(name);\n if (!tool) {\n throw rpcError(JSONRPC_METHOD_NOT_FOUND, `Unknown tool: ${name}`);\n }\n const result = await tool.handler(args);\n return result satisfies CallToolResult;\n }\n\n case \"ping\":\n return {};\n\n default:\n throw rpcError(JSONRPC_METHOD_NOT_FOUND, `Unsupported method: ${method}`);\n }\n }\n\n private scheduleListChangedNotification(): void {\n if (this.notifyListChangedScheduled) return;\n this.notifyListChangedScheduled = true;\n queueMicrotask(() => {\n this.notifyListChangedScheduled = false;\n this.broadcast({ jsonrpc: \"2.0\", method: \"notifications/tools/list_changed\" });\n });\n }\n\n private broadcast(message: JsonRpcMessage): void {\n for (const t of this.transports) t.send(message);\n }\n\n private toRpcError(err: unknown): { code: number; message: string; data?: any } {\n if (err && typeof err === \"object\" && \"code\" in err && \"message\" in err) {\n return err as any;\n }\n return {\n code: JSONRPC_INTERNAL_ERROR,\n message: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\nexport function rpcError(code: number, message: string, data?: any) {\n return { code, message, ...(data !== undefined ? { data } : {}) };\n}\n\n/**\n * Helper to build a CallToolResult from a string or structured value.\n */\nexport function textResult(text: string, structured?: any): CallToolResult {\n return {\n content: [{ type: \"text\", text }],\n ...(structured !== undefined ? { structuredContent: structured } : {}),\n };\n}\n\nexport function errorResult(text: string): CallToolResult {\n return { content: [{ type: \"text\", text }], isError: true };\n}\n\n// Internal helper so the JsonRpcId import isn't dropped by tsup\ntype _KeepIdImport = JsonRpcId;\n","import type { ActivityFilter, AgentActivityEvent, AgentActivityListener } from \"./types\";\n\n/**\n * In-process registry of agent activity events. Bridges call `emitActivity`\n * after a tool runs; React hooks + the SSE relay subscribe via\n * `onActivity()`.\n *\n * Holds a short scrollback of recent events (default 200) so newly-mounted\n * subscribers can render the recent past — useful for activity-log UIs\n * that rejoin a session mid-stream.\n */\n\nconst HISTORY_CAP = 200;\n\nconst listeners = new Set<AgentActivityListener>();\nconst history: AgentActivityEvent[] = [];\n\n/** Emit an activity event. All current listeners receive it synchronously. */\nexport function emitActivity(event: AgentActivityEvent): void {\n history.push(event);\n if (history.length > HISTORY_CAP) history.splice(0, history.length - HISTORY_CAP);\n for (const l of listeners) l(event);\n}\n\n/**\n * Subscribe to all events (or a filtered subset). Returns an unsubscribe\n * function. Filter checks all provided keys with strict equality; omit a\n * key to ignore it.\n */\nexport function onActivity(listener: AgentActivityListener, filter?: ActivityFilter): () => void {\n const wrapped: AgentActivityListener = filter\n ? (e) => { if (matches(e, filter)) listener(e); }\n : listener;\n listeners.add(wrapped);\n return () => listeners.delete(wrapped);\n}\n\n/** Read the recent history (newest last). Optional filter. */\nexport function readActivityHistory(filter?: ActivityFilter): AgentActivityEvent[] {\n if (!filter) return history.slice();\n return history.filter((e) => matches(e, filter));\n}\n\n/** Wipe history + clear listeners. Test/teardown helper. */\nexport function resetActivityRegistry(): void {\n listeners.clear();\n history.length = 0;\n}\n\nfunction matches(e: AgentActivityEvent, f: ActivityFilter): boolean {\n if (f.agentId !== undefined && e.agentId !== f.agentId) return false;\n if (f.screenId !== undefined && e.target.screenId !== f.screenId) return false;\n if (f.kind !== undefined && e.target.kind !== f.kind) return false;\n return true;\n}\n","import type { CallToolResult } from \"../mcp/types\";\nimport { emitActivity } from \"./registry\";\nimport type { AgentTarget } from \"./types\";\n\nexport type ActivityAgent = { id: string; name?: string; color?: string };\n\nexport type ActivityResolverContext<TArgs = Record<string, unknown>> = {\n /** Tool name as registered. */\n toolName: string;\n /** Arguments the tool was called with. */\n args: TArgs;\n /** The CallToolResult the underlying handler produced. */\n result: CallToolResult;\n};\n\n/**\n * Resolves an `AgentTarget` for an executed tool. Bridges declare one of\n * these per registration so the wrapper knows which surface / element /\n * screen the activity belongs to.\n *\n * The resolver runs AFTER the tool handler so it can inspect the result\n * (e.g. read a newly-created item id from `structuredContent`).\n */\nexport type ActivityTargetResolver<TArgs = Record<string, unknown>> = (\n ctx: ActivityResolverContext<TArgs>,\n) => AgentTarget | null;\n\nexport type ToolHandler<TArgs = Record<string, unknown>> = (\n args: TArgs,\n) => Promise<CallToolResult> | CallToolResult;\n\n/**\n * wrapToolWithActivity — decorate a bridge tool handler so every successful\n * call emits an `AgentActivityEvent`. Returns a new handler with the same shape.\n *\n * Usage in a bridge:\n *\n * server.registerTool(\n * definition,\n * wrapToolWithActivity(\n * handler,\n * { agent, kind: \"whiteboard\", resolveTarget: ({ args }) => ({\n * kind: \"whiteboard\", elementId: args.id as string,\n * }) },\n * ),\n * );\n */\nexport function wrapToolWithActivity<TArgs = Record<string, unknown>>(\n handler: ToolHandler<TArgs>,\n options: {\n toolName: string;\n agent: ActivityAgent;\n /** Optional fancy-screens screen id this bridge is scoped to. */\n screenId?: string;\n /** Default target kind if the resolver returns one without `kind`. */\n kind: AgentTarget[\"kind\"];\n /** Per-call resolver. Return `null` to skip emitting (e.g. for read-only tools). */\n resolveTarget?: ActivityTargetResolver<TArgs>;\n /** Optional ttl override. */\n ttlMs?: number;\n },\n): ToolHandler<TArgs> {\n return async (args) => {\n const result = await handler(args);\n if (result.isError) return result;\n\n let target: AgentTarget | null;\n if (options.resolveTarget) {\n target = options.resolveTarget({ toolName: options.toolName, args, result });\n } else {\n target = { kind: options.kind, screenId: options.screenId };\n }\n if (!target) return result;\n\n emitActivity({\n agentId: options.agent.id,\n agentName: options.agent.name,\n agentColor: options.agent.color,\n target: { ...target, kind: target.kind ?? options.kind, screenId: target.screenId ?? options.screenId },\n action: options.toolName,\n timestamp: Date.now(),\n meta: extractMeta(result),\n ttlMs: options.ttlMs,\n });\n return result;\n };\n}\n\nfunction extractMeta(result: CallToolResult): Record<string, unknown> | undefined {\n const sc = result.structuredContent;\n if (sc && typeof sc === \"object\" && !Array.isArray(sc)) {\n return sc as Record<string, unknown>;\n }\n return undefined;\n}\n","/**\n * Generic undo/redo stack keyed by `agentId`. Each entry holds:\n * - `do` — re-applies the action (for redo)\n * - `undo` — reverses it\n * - `label` — human-readable summary surfaced in agent_history\n *\n * Bridges register entries by calling `pushUndoEntry` after a successful\n * mutation. The corresponding MCP tools (`agent_undo`, `agent_redo`,\n * `agent_history`) are registered once per server via `registerUndoTools`.\n *\n * Stacks are per-agent so multiple agents can rewind independently.\n */\n\nexport type UndoEntry = {\n /** Wall-clock ms. */\n timestamp: number;\n /** Bridge id (e.g. \"whiteboard\", \"form:signup\"). */\n bridgeId: string;\n /** Tool name that produced the entry. */\n action: string;\n /** Short human label, e.g. `Added sticky n_abc`. */\n label: string;\n /** Reverse the action. */\n undo: () => void | Promise<void>;\n /** Re-apply the action (used when redoing after an undo). */\n redo: () => void | Promise<void>;\n};\n\ntype Stack = { past: UndoEntry[]; future: UndoEntry[] };\n\nconst stacks = new Map<string, Stack>();\nconst CAP = 200;\n\nfunction getStack(agentId: string): Stack {\n let s = stacks.get(agentId);\n if (!s) {\n s = { past: [], future: [] };\n stacks.set(agentId, s);\n }\n return s;\n}\n\n/** Push a new undo entry on the agent's stack. Clears the redo (future) stack. */\nexport function pushUndoEntry(agentId: string, entry: UndoEntry): void {\n const s = getStack(agentId);\n s.past.push(entry);\n if (s.past.length > CAP) s.past.splice(0, s.past.length - CAP);\n s.future.length = 0;\n}\n\n/** Pop and undo the most recent entry. Returns the entry that ran, or null. */\nexport async function undoOne(agentId: string): Promise<UndoEntry | null> {\n const s = getStack(agentId);\n const entry = s.past.pop();\n if (!entry) return null;\n await entry.undo();\n s.future.push(entry);\n return entry;\n}\n\n/** Re-apply the most recently undone entry. Returns it, or null if no future. */\nexport async function redoOne(agentId: string): Promise<UndoEntry | null> {\n const s = getStack(agentId);\n const entry = s.future.pop();\n if (!entry) return null;\n await entry.redo();\n s.past.push(entry);\n return entry;\n}\n\n/** Read the past stack (oldest first). */\nexport function readHistory(agentId: string): UndoEntry[] {\n return getStack(agentId).past.slice();\n}\n\n/** Wipe an agent's stacks. */\nexport function clearStack(agentId: string): void {\n stacks.delete(agentId);\n}\n\n/** Test/teardown helper. */\nexport function resetAllUndoStacks(): void {\n stacks.clear();\n}\n","import { textResult, errorResult } from \"../mcp/server\";\nimport type { MicroMcpServer } from \"../mcp/server\";\nimport { readHistory, redoOne, undoOne } from \"./undo-stack\";\n\nexport type UndoToolsOptions = {\n /** Default agent id when the caller doesn't pass one. */\n defaultAgentId?: string;\n};\n\n/**\n * Idempotent tracker so multiple bridges on the same server only register\n * agent_undo / agent_redo / agent_history once.\n */\nconst installedServers = new WeakSet<MicroMcpServer>();\n\n/**\n * ensureUndoToolsRegistered — bridges call this on construction. Safe to\n * call repeatedly with the same server; subsequent calls are no-ops.\n */\nexport function ensureUndoToolsRegistered(server: MicroMcpServer, options: UndoToolsOptions = {}): void {\n if (installedServers.has(server)) return;\n installedServers.add(server);\n registerUndoTools(server, options);\n}\n\n/**\n * registerUndoTools — add agent_undo / agent_redo / agent_history to the\n * server. Returns a disposer that unregisters all three.\n */\nexport function registerUndoTools(server: MicroMcpServer, options: UndoToolsOptions = {}): () => void {\n const defaultAgent = options.defaultAgentId ?? \"agent\";\n const disposers: Array<() => void> = [];\n const agentOf = (args: any): string =>\n typeof args?.agentId === \"string\" ? args.agentId : defaultAgent;\n\n disposers.push(\n server.registerTool(\n {\n name: \"agent_undo\",\n description: \"Undo the most recent action on the agent's stack. Optional agentId targets a specific agent.\",\n inputSchema: {\n type: \"object\",\n properties: { agentId: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n async (args) => {\n const entry = await undoOne(agentOf(args));\n if (!entry) return errorResult(\"Nothing to undo.\");\n return textResult(`Undid: ${entry.label}`, { entry: serialize(entry) });\n },\n ),\n );\n\n disposers.push(\n server.registerTool(\n {\n name: \"agent_redo\",\n description: \"Redo the most recently undone action.\",\n inputSchema: {\n type: \"object\",\n properties: { agentId: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n async (args) => {\n const entry = await redoOne(agentOf(args));\n if (!entry) return errorResult(\"Nothing to redo.\");\n return textResult(`Redid: ${entry.label}`, { entry: serialize(entry) });\n },\n ),\n );\n\n disposers.push(\n server.registerTool(\n {\n name: \"agent_history\",\n description: \"List the agent's undo stack (oldest first). Useful for understanding what's reversible.\",\n inputSchema: {\n type: \"object\",\n properties: { agentId: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n async (args) => {\n const history = readHistory(agentOf(args)).map(serialize);\n const text = history.map((e) => `${new Date(e.timestamp).toISOString()} ${e.bridgeId} ${e.action}: ${e.label}`).join(\"\\n\");\n return textResult(text || \"(empty)\", history);\n },\n ),\n );\n\n return () => disposers.forEach((d) => d());\n}\n\nfunction serialize(entry: import(\"./undo-stack\").UndoEntry) {\n return {\n timestamp: entry.timestamp,\n bridgeId: entry.bridgeId,\n action: entry.action,\n label: entry.label,\n };\n}\n","import type {\n BoardItem,\n ConnectorItem,\n RemoteCursor,\n ShapeItem,\n ShapeKind,\n StickyNoteItem,\n Stroke,\n Viewport,\n} from \"@particle-academy/fancy-whiteboard\";\nimport { textResult, errorResult } from \"../mcp/server\";\nimport type { MicroMcpServer } from \"../mcp/server\";\nimport type { JsonObject } from \"../mcp/types\";\nimport type { Bridge } from \"./types\";\nimport { wrapToolWithActivity } from \"../presence/wrap-tool-with-activity\";\nimport type { AgentTarget } from \"../presence/types\";\nimport { pushUndoEntry } from \"../undo/undo-stack\";\nimport { ensureUndoToolsRegistered } from \"../undo/undo-tools\";\n\n/**\n * State accessors / mutators the bridge needs from the host. The host owns\n * whiteboard state (controlled props on fancy-whiteboard components); the\n * bridge calls into these to read or change it.\n */\nexport type WhiteboardBridgeAdapter = {\n getNotes: () => StickyNoteItem[];\n setNotes: (next: StickyNoteItem[] | ((prev: StickyNoteItem[]) => StickyNoteItem[])) => void;\n getShapes: () => ShapeItem[];\n setShapes: (next: ShapeItem[] | ((prev: ShapeItem[]) => ShapeItem[])) => void;\n getConnectors: () => ConnectorItem[];\n setConnectors: (next: ConnectorItem[] | ((prev: ConnectorItem[]) => ConnectorItem[])) => void;\n getStrokes: () => Stroke[];\n setStrokes: (next: Stroke[] | ((prev: Stroke[]) => Stroke[])) => void;\n getViewport: () => Viewport;\n setViewport: (next: Viewport) => void;\n /** Optional: agent presence cursor (for the visualizer). */\n setAgentCursor?: (cursor: RemoteCursor | null) => void;\n};\n\nexport type WhiteboardBridgeOptions = {\n adapter: WhiteboardBridgeAdapter;\n /** Identity used when the agent stamps authorId on items / cursor. */\n agent?: { id: string; name?: string; color?: string };\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\nconst VALID_SHAPES: ShapeKind[] = [\"rect\", \"rounded-rect\", \"ellipse\", \"diamond\", \"triangle\", \"line\", \"arrow\", \"text\"];\n\nconst num = (v: unknown, fallback?: number): number =>\n typeof v === \"number\" && Number.isFinite(v) ? v : fallback ?? 0;\nconst str = (v: unknown, fallback = \"\"): string => (typeof v === \"string\" ? v : fallback);\nconst bool = (v: unknown, fallback = false): boolean => (typeof v === \"boolean\" ? v : fallback);\n\nconst newId = (prefix: string) =>\n `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`;\n\n/**\n * registerWhiteboardBridge — wires a full MCP tool set against a fancy-\n * whiteboard session controlled by the host. Returns a Bridge handle the\n * host can dispose to tear everything down.\n */\nexport function registerWhiteboardBridge(\n server: MicroMcpServer,\n options: WhiteboardBridgeOptions,\n): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const disposers: Array<() => void> = [];\n\n // Register agent_undo / agent_redo / agent_history once per server. Idempotent.\n ensureUndoToolsRegistered(server, { defaultAgentId: agent.id });\n\n // Cursor narration is the agent's responsibility — call\n // whiteboard_set_agent_cursor as a separate prerequisite before any\n // mutation. This keeps the protocol honest: each tool does one thing.\n\n // Activity-target resolver shared by every mutation tool. Pulls the id\n // from the freshly-created item (structuredContent) when present, falls\n // back to the args id (for update/delete tools).\n const wbTarget = (args: any, result: any): AgentTarget => ({\n kind: \"whiteboard\",\n elementId: (result?.structuredContent?.id as string | undefined) ?? (args?.id as string | undefined),\n });\n\n\n const reg = (\n name: string,\n description: string,\n inputProperties: Record<string, unknown>,\n required: string[],\n handler: (args: JsonObject) => Promise<any> | any,\n /** Optional: resolve the activity target so the presence layer can render\n * a focus indicator on the touched element. Read tools omit this. */\n resolveTarget?: (args: JsonObject, result: any) => AgentTarget | null,\n ) => {\n const wrapped = async (args: JsonObject) => {\n try {\n return await handler(args);\n } catch (e) {\n return errorResult(e instanceof Error ? e.message : String(e));\n }\n };\n const final = resolveTarget\n ? wrapToolWithActivity(wrapped, {\n toolName: name,\n agent: { id: agent.id, name: agent.name, color: agent.color },\n kind: \"whiteboard\",\n resolveTarget: ({ args, result }) => resolveTarget(args, result),\n })\n : wrapped;\n disposers.push(\n server.registerTool(\n {\n name,\n description,\n inputSchema: {\n type: \"object\",\n properties: inputProperties as any,\n required,\n additionalProperties: false,\n },\n },\n final as any,\n ),\n );\n };\n\n // ───────────── Read tools ─────────────\n\n reg(\"whiteboard_get_state\", \"Get the full board state: viewport, all items, strokes.\", {}, [], () => {\n const state = {\n viewport: adapter.getViewport(),\n notes: adapter.getNotes(),\n shapes: adapter.getShapes(),\n connectors: adapter.getConnectors(),\n strokes: adapter.getStrokes(),\n };\n return textResult(JSON.stringify(state, null, 2), state);\n });\n\n reg(\"whiteboard_list_items\", \"List notes, shapes, and connectors with id, kind, and bounds.\", {}, [], () => {\n const items: Array<{ id: string; kind: string; summary: string }> = [];\n for (const n of adapter.getNotes()) {\n items.push({\n id: n.id,\n kind: \"sticky\",\n summary: `\"${(n.text ?? \"\").slice(0, 40)}\" @(${Math.round(n.x)},${Math.round(n.y)}) ${n.width}×${n.height}`,\n });\n }\n for (const s of adapter.getShapes()) {\n items.push({\n id: s.id,\n kind: `shape:${s.shape}`,\n summary: `${s.text ? `\"${s.text}\" ` : \"\"}@(${Math.round(s.x)},${Math.round(s.y)}) ${s.width}×${s.height}`,\n });\n }\n for (const c of adapter.getConnectors()) {\n items.push({ id: c.id, kind: \"connector\", summary: `from=${JSON.stringify(c.from)} to=${JSON.stringify(c.to)}` });\n }\n return textResult(items.map((i) => `${i.kind} ${i.id}: ${i.summary}`).join(\"\\n\") || \"(empty board)\", items);\n });\n\n reg(\n \"whiteboard_get_item\",\n \"Get a single item (sticky / shape / connector) by id.\",\n { id: { type: \"string\" } },\n [\"id\"],\n (args) => {\n const id = str(args.id);\n const all: BoardItem[] = [...adapter.getNotes(), ...adapter.getShapes(), ...adapter.getConnectors()];\n const found = all.find((x) => x.id === id);\n if (!found) return errorResult(`No item with id ${id}`);\n return textResult(JSON.stringify(found, null, 2), found);\n },\n );\n\n // ───────────── Sticky CRUD ─────────────\n\n reg(\n \"whiteboard_add_sticky\",\n \"Add a sticky note. Position is in world coordinates.\",\n {\n x: { type: \"number\" },\n y: { type: \"number\" },\n text: { type: \"string\" },\n width: { type: \"number\" },\n height: { type: \"number\" },\n color: { type: \"string\", description: \"CSS color, e.g. #fde68a\" },\n },\n [\"x\", \"y\"],\n async (args) => {\n const x = num(args.x);\n const y = num(args.y);\n const width = num(args.width, 180);\n const height = num(args.height, 140);\n// (cursor narration is now an explicit separate tool call)\n const note: StickyNoteItem = {\n id: newId(\"n\"),\n kind: \"sticky\",\n x, y, width, height,\n text: str(args.text),\n color: typeof args.color === \"string\" ? args.color : \"#fde68a\",\n authorId: agent.id,\n };\n adapter.setNotes((all) => [...all, note]);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"whiteboard\",\n action: \"whiteboard_add_sticky\",\n label: `Added sticky ${note.id}`,\n undo: () => adapter.setNotes((all) => all.filter((n) => n.id !== note.id)),\n redo: () => adapter.setNotes((all) => [...all, note]),\n });\n return textResult(`Added sticky ${note.id}`, note);\n },\n wbTarget,\n );\n\n reg(\n \"whiteboard_stream_text\",\n \"Type text into a sticky note character-by-character so the human can read it forming. The tool returns once streaming finishes.\",\n {\n id: { type: \"string\" },\n text: { type: \"string\" },\n cps: { type: \"number\", description: \"Characters per second. Default 25.\" },\n append: { type: \"boolean\", description: \"Append to existing text instead of replacing. Default false.\" },\n },\n [\"id\", \"text\"],\n async (args) => {\n const id = str(args.id);\n const target = str(args.text);\n const cps = Math.max(1, num(args.cps, 25));\n const append = bool(args.append);\n const startNote = adapter.getNotes().find((n) => n.id === id);\n if (!startNote) return errorResult(`No sticky with id ${id}`);\n const base = append ? (startNote.text ?? \"\") : \"\";\n const interval = Math.max(8, Math.round(1000 / cps));\n for (let i = 0; i <= target.length; i++) {\n const nextText = base + target.slice(0, i);\n adapter.setNotes((all) => all.map((n) => (n.id === id ? { ...n, text: nextText } : n)));\n if (i < target.length) await new Promise((r) => setTimeout(r, interval));\n }\n return textResult(`Streamed ${target.length} chars to ${id}`, { id, text: base + target });\n },\n );\n\n reg(\n \"whiteboard_update_sticky\",\n \"Update fields on a sticky note. Only provided fields are changed.\",\n {\n id: { type: \"string\" },\n x: { type: \"number\" },\n y: { type: \"number\" },\n width: { type: \"number\" },\n height: { type: \"number\" },\n text: { type: \"string\" },\n color: { type: \"string\" },\n },\n [\"id\"],\n async (args) => {\n const id = str(args.id);\n const existing = adapter.getNotes().find((n) => n.id === id);\n if (!existing) return errorResult(`No sticky with id ${id}`);\n const nextX = args.x !== undefined ? num(args.x) : existing.x;\n const nextY = args.y !== undefined ? num(args.y) : existing.y;\n const nextW = args.width !== undefined ? num(args.width) : existing.width;\n const nextH = args.height !== undefined ? num(args.height) : existing.height;\n// (cursor narration is now an explicit separate tool call)\n let updated: StickyNoteItem | null = null;\n adapter.setNotes((all) =>\n all.map((n) => {\n if (n.id !== id) return n;\n updated = {\n ...n,\n x: nextX, y: nextY, width: nextW, height: nextH,\n ...(args.text !== undefined ? { text: str(args.text) } : {}),\n ...(args.color !== undefined ? { color: str(args.color) } : {}),\n };\n return updated;\n }),\n );\n return textResult(`Updated sticky ${id}`, updated);\n },\n wbTarget,\n );\n\n // ───────────── Shape CRUD ─────────────\n\n reg(\n \"whiteboard_add_shape\",\n `Add a shape. Kind must be one of: ${VALID_SHAPES.join(\", \")}.`,\n {\n shape: { type: \"string\", enum: VALID_SHAPES },\n x: { type: \"number\" },\n y: { type: \"number\" },\n width: { type: \"number\" },\n height: { type: \"number\" },\n text: { type: \"string\" },\n fill: { type: \"string\" },\n stroke: { type: \"string\" },\n flipX: { type: \"boolean\" },\n flipY: { type: \"boolean\" },\n },\n [\"shape\", \"x\", \"y\", \"width\", \"height\"],\n async (args) => {\n const kind = str(args.shape) as ShapeKind;\n if (!VALID_SHAPES.includes(kind)) return errorResult(`Invalid shape kind: ${kind}`);\n const x = num(args.x);\n const y = num(args.y);\n const width = num(args.width);\n const height = num(args.height);\n// (cursor narration is now an explicit separate tool call)\n const shape: ShapeItem = {\n id: newId(\"s\"),\n kind: \"shape\",\n shape: kind,\n x, y, width, height,\n ...(args.text !== undefined ? { text: str(args.text) } : {}),\n ...(args.fill !== undefined ? { fill: str(args.fill) } : {}),\n ...(args.stroke !== undefined ? { stroke: str(args.stroke) } : {}),\n ...(args.flipX !== undefined ? { flipX: bool(args.flipX) } : {}),\n ...(args.flipY !== undefined ? { flipY: bool(args.flipY) } : {}),\n };\n adapter.setShapes((all) => [...all, shape]);\n return textResult(`Added ${kind} ${shape.id}`, shape);\n },\n wbTarget,\n );\n\n reg(\n \"whiteboard_update_shape\",\n \"Update fields on a shape.\",\n {\n id: { type: \"string\" },\n x: { type: \"number\" },\n y: { type: \"number\" },\n width: { type: \"number\" },\n height: { type: \"number\" },\n text: { type: \"string\" },\n fill: { type: \"string\" },\n stroke: { type: \"string\" },\n },\n [\"id\"],\n async (args) => {\n const id = str(args.id);\n const existing = adapter.getShapes().find((s) => s.id === id);\n if (!existing) return errorResult(`No shape with id ${id}`);\n const nextX = args.x !== undefined ? num(args.x) : existing.x;\n const nextY = args.y !== undefined ? num(args.y) : existing.y;\n const nextW = args.width !== undefined ? num(args.width) : existing.width;\n const nextH = args.height !== undefined ? num(args.height) : existing.height;\n// (cursor narration is now an explicit separate tool call)\n let updated: ShapeItem | null = null;\n adapter.setShapes((all) =>\n all.map((s) => {\n if (s.id !== id) return s;\n updated = {\n ...s,\n x: nextX, y: nextY, width: nextW, height: nextH,\n ...(args.text !== undefined ? { text: str(args.text) } : {}),\n ...(args.fill !== undefined ? { fill: str(args.fill) } : {}),\n ...(args.stroke !== undefined ? { stroke: str(args.stroke) } : {}),\n };\n return updated;\n }),\n );\n return textResult(`Updated shape ${id}`, updated);\n },\n wbTarget,\n );\n\n // ───────────── Connectors ─────────────\n\n reg(\n \"whiteboard_add_connector\",\n \"Connect two items by id, or specify explicit world-space points.\",\n {\n from: { description: \"Item id (string) or {x,y}\" },\n to: { description: \"Item id (string) or {x,y}\" },\n color: { type: \"string\" },\n },\n [\"from\", \"to\"],\n (args) => {\n const c: ConnectorItem = {\n id: newId(\"c\"),\n kind: \"connector\",\n from: args.from as any,\n to: args.to as any,\n ...(args.color !== undefined ? { color: str(args.color) } : {}),\n };\n adapter.setConnectors((all) => [...all, c]);\n return textResult(`Added connector ${c.id}`, c);\n },\n wbTarget,\n );\n\n // ───────────── Drawing ─────────────\n\n reg(\n \"whiteboard_add_stroke\",\n \"Add a freeform pen stroke. Points are absolute screen coords (matching the Drawing layer).\",\n {\n points: {\n type: \"array\",\n description: \"Array of {x,y} points\",\n },\n color: { type: \"string\" },\n size: { type: \"number\" },\n },\n [\"points\"],\n (args) => {\n const points = (Array.isArray(args.points) ? args.points : []).map((p: any) => ({\n x: num(p?.x),\n y: num(p?.y),\n }));\n if (!points.length) return errorResult(\"Stroke requires at least one point\");\n const stroke: Stroke = {\n id: newId(\"st\"),\n points,\n color: typeof args.color === \"string\" ? args.color : \"#0f172a\",\n size: typeof args.size === \"number\" ? args.size : 2,\n authorId: agent.id,\n };\n adapter.setStrokes((all) => [...all, stroke]);\n return textResult(`Added stroke ${stroke.id} (${points.length} points)`, stroke);\n },\n wbTarget,\n );\n\n // ───────────── Generic delete ─────────────\n\n reg(\n \"whiteboard_delete_item\",\n \"Remove any item by id (sticky / shape / connector / stroke).\",\n { id: { type: \"string\" } },\n [\"id\"],\n (args) => {\n const id = str(args.id);\n // Snapshot the items being removed so undo can re-insert them.\n const removedNotes = adapter.getNotes().filter((x) => x.id === id);\n const removedShapes = adapter.getShapes().filter((x) => x.id === id);\n const removedConnectors = adapter.getConnectors().filter((x) => x.id === id);\n const removedStrokes = adapter.getStrokes().filter((x) => x.id === id);\n const removed = removedNotes.length + removedShapes.length + removedConnectors.length + removedStrokes.length > 0;\n if (!removed) return errorResult(`No item with id ${id}`);\n adapter.setNotes((all) => all.filter((x) => x.id !== id));\n adapter.setShapes((all) => all.filter((x) => x.id !== id));\n adapter.setConnectors((all) => all.filter((x) => x.id !== id));\n adapter.setStrokes((all) => all.filter((x) => x.id !== id));\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"whiteboard\",\n action: \"whiteboard_delete_item\",\n label: `Deleted ${id}`,\n undo: () => {\n if (removedNotes.length) adapter.setNotes((all) => [...all, ...removedNotes]);\n if (removedShapes.length) adapter.setShapes((all) => [...all, ...removedShapes]);\n if (removedConnectors.length) adapter.setConnectors((all) => [...all, ...removedConnectors]);\n if (removedStrokes.length) adapter.setStrokes((all) => [...all, ...removedStrokes]);\n },\n redo: () => {\n adapter.setNotes((all) => all.filter((x) => x.id !== id));\n adapter.setShapes((all) => all.filter((x) => x.id !== id));\n adapter.setConnectors((all) => all.filter((x) => x.id !== id));\n adapter.setStrokes((all) => all.filter((x) => x.id !== id));\n },\n });\n return textResult(`Deleted ${id}`);\n },\n wbTarget,\n );\n\n // ───────────── Viewport / agent presence ─────────────\n\n reg(\n \"whiteboard_set_viewport\",\n \"Pan / zoom the viewport.\",\n { x: { type: \"number\" }, y: { type: \"number\" }, zoom: { type: \"number\" } },\n [],\n (args) => {\n const v = adapter.getViewport();\n const next: Viewport = {\n x: args.x !== undefined ? num(args.x) : v.x,\n y: args.y !== undefined ? num(args.y) : v.y,\n zoom: args.zoom !== undefined ? num(args.zoom) : v.zoom,\n };\n adapter.setViewport(next);\n return textResult(`Viewport → ${JSON.stringify(next)}`, next);\n },\n wbTarget,\n );\n\n reg(\n \"whiteboard_set_agent_cursor\",\n \"Move the agent's presence cursor (or pass null to hide it).\",\n {\n x: { type: \"number\" },\n y: { type: \"number\" },\n hide: { type: \"boolean\" },\n },\n [],\n (args) => {\n if (!adapter.setAgentCursor) return errorResult(\"Host did not provide setAgentCursor\");\n if (bool(args.hide)) {\n adapter.setAgentCursor(null);\n return textResult(\"Agent cursor hidden\");\n }\n const cursor: RemoteCursor = {\n userId: agent.id,\n name: agent.name,\n color: agent.color,\n x: num(args.x),\n y: num(args.y),\n };\n adapter.setAgentCursor(cursor);\n return textResult(`Cursor → (${cursor.x}, ${cursor.y})`, cursor);\n },\n wbTarget,\n );\n\n return {\n id: \"whiteboard\",\n title: \"Whiteboard\",\n dispose: () => {\n for (const d of disposers) d();\n adapter.setAgentCursor?.(null);\n },\n };\n}\n"]}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
export { registerWhiteboardBridge } from './chunk-
|
|
1
|
+
export { registerWhiteboardBridge } from './chunk-TBEITXF4.js';
|
|
2
|
+
import './chunk-ACBENYYO.js';
|
|
3
|
+
import './chunk-52S7XYZK.js';
|
|
4
|
+
import './chunk-JU2N4KK6.js';
|
|
2
5
|
import './chunk-QGCF7YKW.js';
|
|
3
6
|
//# sourceMappingURL=bridges-whiteboard.js.map
|
|
4
7
|
//# sourceMappingURL=bridges-whiteboard.js.map
|