@particle-academy/agent-integrations 0.3.4 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/README.md +20 -0
  2. package/dist/bridges/charts.d.cts +4 -4
  3. package/dist/bridges/charts.d.ts +4 -4
  4. package/dist/bridges/code.d.cts +4 -4
  5. package/dist/bridges/code.d.ts +4 -4
  6. package/dist/bridges/flow.d.cts +4 -4
  7. package/dist/bridges/flow.d.ts +4 -4
  8. package/dist/bridges/forms.d.cts +4 -4
  9. package/dist/bridges/forms.d.ts +4 -4
  10. package/dist/bridges/scene.d.cts +4 -4
  11. package/dist/bridges/scene.d.ts +4 -4
  12. package/dist/bridges/screens.d.cts +78 -0
  13. package/dist/bridges/screens.d.ts +78 -0
  14. package/dist/bridges/sheets.d.cts +4 -4
  15. package/dist/bridges/sheets.d.ts +4 -4
  16. package/dist/bridges/whiteboard.d.cts +4 -4
  17. package/dist/bridges/whiteboard.d.ts +4 -4
  18. package/dist/bridges-charts.cjs +2 -2
  19. package/dist/bridges-charts.cjs.map +1 -1
  20. package/dist/bridges-charts.js +2 -2
  21. package/dist/bridges-code.cjs +2 -2
  22. package/dist/bridges-code.cjs.map +1 -1
  23. package/dist/bridges-code.js +2 -2
  24. package/dist/bridges-flow.cjs +2 -2
  25. package/dist/bridges-flow.cjs.map +1 -1
  26. package/dist/bridges-flow.js +2 -2
  27. package/dist/bridges-forms.cjs +2 -2
  28. package/dist/bridges-forms.cjs.map +1 -1
  29. package/dist/bridges-forms.js +2 -2
  30. package/dist/bridges-scene.cjs +2 -2
  31. package/dist/bridges-scene.cjs.map +1 -1
  32. package/dist/bridges-scene.js +2 -2
  33. package/dist/bridges-screens.cjs +227 -0
  34. package/dist/bridges-screens.cjs.map +1 -0
  35. package/dist/bridges-screens.js +6 -0
  36. package/dist/bridges-screens.js.map +1 -0
  37. package/dist/bridges-sheets.cjs +2 -2
  38. package/dist/bridges-sheets.cjs.map +1 -1
  39. package/dist/bridges-sheets.js +2 -2
  40. package/dist/bridges-whiteboard.cjs +12 -12
  41. package/dist/bridges-whiteboard.cjs.map +1 -1
  42. package/dist/bridges-whiteboard.js +3 -3
  43. package/dist/{chunk-TBEITXF4.js → chunk-3KSZNGNW.js} +7 -7
  44. package/dist/chunk-3KSZNGNW.js.map +1 -0
  45. package/dist/{chunk-OEIULP2L.js → chunk-4BL5M3U3.js} +5 -5
  46. package/dist/chunk-4BL5M3U3.js.map +1 -0
  47. package/dist/{chunk-QGCF7YKW.js → chunk-4KAIV6OD.js} +40 -12
  48. package/dist/chunk-4KAIV6OD.js.map +1 -0
  49. package/dist/chunk-57ZDHD53.js +180 -0
  50. package/dist/chunk-57ZDHD53.js.map +1 -0
  51. package/dist/chunk-E4AICMFZ.js +83 -0
  52. package/dist/chunk-E4AICMFZ.js.map +1 -0
  53. package/dist/{chunk-ACBENYYO.js → chunk-GQ7XXK7G.js} +12 -12
  54. package/dist/chunk-GQ7XXK7G.js.map +1 -0
  55. package/dist/{chunk-XYYSTJHW.js → chunk-HSTW7ZNO.js} +5 -5
  56. package/dist/chunk-HSTW7ZNO.js.map +1 -0
  57. package/dist/{chunk-PDBF4W7E.js → chunk-IANI25IT.js} +5 -5
  58. package/dist/chunk-IANI25IT.js.map +1 -0
  59. package/dist/{chunk-4IAVAFUV.js → chunk-N3H4DXY5.js} +5 -5
  60. package/dist/chunk-N3H4DXY5.js.map +1 -0
  61. package/dist/{chunk-PHPXKSWI.js → chunk-NTDZWGYB.js} +5 -5
  62. package/dist/chunk-NTDZWGYB.js.map +1 -0
  63. package/dist/{chunk-DJOWMF6Q.js → chunk-RGO42EQ6.js} +3 -3
  64. package/dist/{chunk-DJOWMF6Q.js.map → chunk-RGO42EQ6.js.map} +1 -1
  65. package/dist/{chunk-QJUTISFC.js → chunk-XRAJSOPS.js} +5 -5
  66. package/dist/chunk-XRAJSOPS.js.map +1 -0
  67. package/dist/index.cjs +320 -35
  68. package/dist/index.cjs.map +1 -1
  69. package/dist/index.d.cts +7 -4
  70. package/dist/index.d.ts +7 -4
  71. package/dist/index.js +15 -13
  72. package/dist/index.js.map +1 -1
  73. package/dist/mcp/index.d.cts +5 -4
  74. package/dist/mcp/index.d.ts +5 -4
  75. package/dist/mcp.cjs +37 -9
  76. package/dist/mcp.cjs.map +1 -1
  77. package/dist/mcp.js +1 -1
  78. package/dist/presence/index.d.cts +1 -1
  79. package/dist/presence/index.d.ts +1 -1
  80. package/dist/{server-BJu_AMH3.d.ts → server-BsSwfemr.d.cts} +4 -5
  81. package/dist/{server-si-VvFxI.d.cts → server-Du3-IGqM.d.ts} +4 -5
  82. package/dist/sharing/index.d.cts +3 -2
  83. package/dist/sharing/index.d.ts +3 -2
  84. package/dist/sheets-adapter.cjs +96 -0
  85. package/dist/sheets-adapter.cjs.map +1 -0
  86. package/dist/sheets-adapter.d.cts +115 -0
  87. package/dist/sheets-adapter.d.ts +115 -0
  88. package/dist/sheets-adapter.js +4 -0
  89. package/dist/sheets-adapter.js.map +1 -0
  90. package/dist/tool-host-BQuUygLF.d.cts +60 -0
  91. package/dist/tool-host-C8JMMGYq.d.ts +60 -0
  92. package/dist/{types-DXKpLuia.d.ts → types-CCSBGW9T.d.cts} +2 -2
  93. package/dist/{types-Bf1ZoGmI.d.cts → types-DIVNcIQO.d.ts} +2 -2
  94. package/dist/{types-DksGd5Y7.d.cts → types-aOQLTW0E.d.cts} +1 -1
  95. package/dist/{types-DksGd5Y7.d.ts → types-aOQLTW0E.d.ts} +1 -1
  96. package/dist/undo/index.d.cts +4 -4
  97. package/dist/undo/index.d.ts +4 -4
  98. package/dist/undo.cjs +9 -9
  99. package/dist/undo.cjs.map +1 -1
  100. package/dist/undo.js +3 -3
  101. package/package.json +1 -1
  102. package/dist/chunk-4IAVAFUV.js.map +0 -1
  103. package/dist/chunk-ACBENYYO.js.map +0 -1
  104. package/dist/chunk-OEIULP2L.js.map +0 -1
  105. package/dist/chunk-PDBF4W7E.js.map +0 -1
  106. package/dist/chunk-PHPXKSWI.js.map +0 -1
  107. package/dist/chunk-QGCF7YKW.js.map +0 -1
  108. package/dist/chunk-QJUTISFC.js.map +0 -1
  109. package/dist/chunk-TBEITXF4.js.map +0 -1
  110. package/dist/chunk-XYYSTJHW.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -63,10 +63,43 @@ var JSONRPC_INVALID_PARAMS = -32602;
63
63
  var JSONRPC_INTERNAL_ERROR = -32603;
64
64
  var MCP_PROTOCOL_VERSION = "2025-06-18";
65
65
 
66
+ // src/mcp/tool-host.ts
67
+ var ToolRegistry = class {
68
+ constructor() {
69
+ this.tools = /* @__PURE__ */ new Map();
70
+ }
71
+ registerTool(definition, handler) {
72
+ this.tools.set(definition.name, { definition, handler });
73
+ this.onToolsChanged();
74
+ return () => {
75
+ if (this.tools.delete(definition.name)) this.onToolsChanged();
76
+ };
77
+ }
78
+ getTool(name) {
79
+ return this.tools.get(name) ?? null;
80
+ }
81
+ listTools() {
82
+ return Array.from(this.tools.values()).map((t) => t.definition);
83
+ }
84
+ async callTool(name, args = {}) {
85
+ const tool = this.tools.get(name);
86
+ if (!tool) {
87
+ throw new Error(`Unknown tool: ${name}`);
88
+ }
89
+ return tool.handler(args);
90
+ }
91
+ /**
92
+ * Hook for subclasses (e.g. MicroMcpServer) to notify subscribers
93
+ * when the tool catalog changes. Default no-op.
94
+ */
95
+ onToolsChanged() {
96
+ }
97
+ };
98
+
66
99
  // src/mcp/server.ts
67
- var MicroMcpServer = class {
100
+ var MicroMcpServer = class extends ToolRegistry {
68
101
  constructor(options) {
69
- this.tools = /* @__PURE__ */ new Map();
102
+ super();
70
103
  this.transports = /* @__PURE__ */ new Set();
71
104
  this.notifyListChangedScheduled = false;
72
105
  this.info = options.info;
@@ -82,18 +115,13 @@ var MicroMcpServer = class {
82
115
  transport.close?.();
83
116
  }
84
117
  }
85
- registerTool(definition, handler) {
86
- this.tools.set(definition.name, { definition, handler });
87
- this.scheduleListChangedNotification();
88
- return () => this.unregisterTool(definition.name);
89
- }
90
118
  unregisterTool(name) {
91
119
  if (this.tools.delete(name)) {
92
120
  this.scheduleListChangedNotification();
93
121
  }
94
122
  }
95
- listTools() {
96
- return Array.from(this.tools.values()).map((t) => t.definition);
123
+ onToolsChanged() {
124
+ this.scheduleListChangedNotification();
97
125
  }
98
126
  /**
99
127
  * Receive a JSON-RPC frame from a client (called by the transport).
@@ -325,18 +353,18 @@ function resetAllUndoStacks() {
325
353
  }
326
354
 
327
355
  // src/undo/undo-tools.ts
328
- var installedServers = /* @__PURE__ */ new WeakSet();
329
- function ensureUndoToolsRegistered(server, options = {}) {
330
- if (installedServers.has(server)) return;
331
- installedServers.add(server);
332
- registerUndoTools(server, options);
356
+ var installedHosts = /* @__PURE__ */ new WeakSet();
357
+ function ensureUndoToolsRegistered(host, options = {}) {
358
+ if (installedHosts.has(host)) return;
359
+ installedHosts.add(host);
360
+ registerUndoTools(host, options);
333
361
  }
334
- function registerUndoTools(server, options = {}) {
362
+ function registerUndoTools(host, options = {}) {
335
363
  const defaultAgent = options.defaultAgentId ?? "agent";
336
364
  const disposers = [];
337
365
  const agentOf = (args) => typeof args?.agentId === "string" ? args.agentId : defaultAgent;
338
366
  disposers.push(
339
- server.registerTool(
367
+ host.registerTool(
340
368
  {
341
369
  name: "agent_undo",
342
370
  description: "Undo the most recent action on the agent's stack. Optional agentId targets a specific agent.",
@@ -354,7 +382,7 @@ function registerUndoTools(server, options = {}) {
354
382
  )
355
383
  );
356
384
  disposers.push(
357
- server.registerTool(
385
+ host.registerTool(
358
386
  {
359
387
  name: "agent_redo",
360
388
  description: "Redo the most recently undone action.",
@@ -372,7 +400,7 @@ function registerUndoTools(server, options = {}) {
372
400
  )
373
401
  );
374
402
  disposers.push(
375
- server.registerTool(
403
+ host.registerTool(
376
404
  {
377
405
  name: "agent_history",
378
406
  description: "List the agent's undo stack (oldest first). Useful for understanding what's reversible.",
@@ -407,11 +435,11 @@ var num = (v, fallback) => typeof v === "number" && Number.isFinite(v) ? v : fal
407
435
  var str = (v, fallback = "") => typeof v === "string" ? v : fallback;
408
436
  var bool = (v, fallback = false) => typeof v === "boolean" ? v : fallback;
409
437
  var newId = (prefix) => `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`;
410
- function registerWhiteboardBridge(server, options) {
438
+ function registerWhiteboardBridge(host, options) {
411
439
  const { adapter } = options;
412
440
  const agent = { ...DEFAULT_AGENT, ...options.agent ?? {} };
413
441
  const disposers = [];
414
- ensureUndoToolsRegistered(server, { defaultAgentId: agent.id });
442
+ ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
415
443
  const wbTarget = (args, result) => ({
416
444
  kind: "whiteboard",
417
445
  elementId: result?.structuredContent?.id ?? args?.id
@@ -431,7 +459,7 @@ function registerWhiteboardBridge(server, options) {
431
459
  resolveTarget: ({ args, result }) => resolveTarget(args, result)
432
460
  }) : wrapped;
433
461
  disposers.push(
434
- server.registerTool(
462
+ host.registerTool(
435
463
  {
436
464
  name,
437
465
  description,
@@ -834,7 +862,7 @@ var DEFAULT_AGENT2 = { id: "agent", name: "Agent", color: "#a855f7" };
834
862
  var num2 = (v, fallback) => typeof v === "number" && Number.isFinite(v) ? v : 0;
835
863
  var str2 = (v, fallback = "") => typeof v === "string" ? v : fallback;
836
864
  var newId2 = (prefix) => `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`;
837
- function registerFlowBridge(server, options) {
865
+ function registerFlowBridge(host, options) {
838
866
  const { adapter } = options;
839
867
  const agent = { ...DEFAULT_AGENT2, ...options.agent ?? {} };
840
868
  const disposers = [];
@@ -857,7 +885,7 @@ function registerFlowBridge(server, options) {
857
885
  resolveTarget: ({ args, result }) => resolveTarget(args, result)
858
886
  }) : wrapped;
859
887
  disposers.push(
860
- server.registerTool(
888
+ host.registerTool(
861
889
  {
862
890
  name,
863
891
  description,
@@ -1167,7 +1195,7 @@ function registerFlowBridge(server, options) {
1167
1195
 
1168
1196
  // src/bridges/forms.ts
1169
1197
  var DEFAULT_AGENT3 = { id: "agent", name: "Agent", color: "#a855f7" };
1170
- function registerFormBridge(server, options) {
1198
+ function registerFormBridge(host, options) {
1171
1199
  const { adapter } = options;
1172
1200
  const agent = { ...DEFAULT_AGENT3, ...options.agent ?? {} };
1173
1201
  const disposers = [];
@@ -1194,7 +1222,7 @@ function registerFormBridge(server, options) {
1194
1222
  resolveTarget: ({ args }) => target(args)
1195
1223
  }) : wrapped;
1196
1224
  disposers.push(
1197
- server.registerTool(
1225
+ host.registerTool(
1198
1226
  {
1199
1227
  name,
1200
1228
  description,
@@ -1319,7 +1347,7 @@ function registerFormBridge(server, options) {
1319
1347
 
1320
1348
  // src/bridges/sheets.ts
1321
1349
  var DEFAULT_AGENT4 = { id: "agent", name: "Agent", color: "#a855f7" };
1322
- function registerSheetsBridge(server, options) {
1350
+ function registerSheetsBridge(host, options) {
1323
1351
  const { adapter } = options;
1324
1352
  const agent = { ...DEFAULT_AGENT4, ...options.agent ?? {} };
1325
1353
  const disposers = [];
@@ -1345,7 +1373,7 @@ function registerSheetsBridge(server, options) {
1345
1373
  resolveTarget: ({ args, result }) => resolveTarget?.(args, result) ?? target(getSheetId(args))
1346
1374
  }) : wrapped;
1347
1375
  disposers.push(
1348
- server.registerTool(
1376
+ host.registerTool(
1349
1377
  {
1350
1378
  name,
1351
1379
  description,
@@ -1591,9 +1619,88 @@ function readRange(sheet, startAddr, endAddr) {
1591
1619
  return grid;
1592
1620
  }
1593
1621
 
1622
+ // src/sheets-adapter.ts
1623
+ init_registry();
1624
+ function useSheetsAdapter(initial, options = {}) {
1625
+ const [workbook, setWorkbook] = react.useState(initial);
1626
+ const [activeCell, setActiveCellState] = react.useState(null);
1627
+ const workbookRef = react.useRef(workbook);
1628
+ workbookRef.current = workbook;
1629
+ const setActiveCell = react.useCallback((sheetId, address) => {
1630
+ setWorkbook((cur) => cur.activeSheetId === sheetId ? cur : { ...cur, activeSheetId: sheetId });
1631
+ setActiveCellState(address);
1632
+ }, []);
1633
+ const onActiveCellChange = react.useCallback((address) => {
1634
+ setActiveCellState(address);
1635
+ }, []);
1636
+ const setWorkbookRef = react.useRef(setWorkbook);
1637
+ setWorkbookRef.current = setWorkbook;
1638
+ const adapter = react.useMemo(
1639
+ () => ({
1640
+ screenId: options.screenId,
1641
+ getWorkbook: () => workbookRef.current,
1642
+ setWorkbook: (next) => setWorkbookRef.current(next),
1643
+ setActiveCell
1644
+ }),
1645
+ [options.screenId, setActiveCell]
1646
+ );
1647
+ return {
1648
+ workbook,
1649
+ setWorkbook,
1650
+ onActiveCellChange,
1651
+ adapter,
1652
+ setActiveCell,
1653
+ activeCell
1654
+ };
1655
+ }
1656
+ function useSheetsActivityHighlights(options = {}) {
1657
+ const ttlMs = options.ttlMs ?? 2200;
1658
+ const screenId = options.screenId;
1659
+ const [, force] = react.useState(0);
1660
+ const hitsRef = react.useRef(/* @__PURE__ */ new Map());
1661
+ react.useEffect(() => {
1662
+ const off = onActivity((event) => {
1663
+ if (event.target?.kind !== "sheet") return;
1664
+ if (screenId && event.target.screenId && event.target.screenId !== screenId) return;
1665
+ const elementId = event.target.elementId;
1666
+ if (!elementId || !elementId.includes("!")) return;
1667
+ hitsRef.current.set(elementId, { event, expiresAt: Date.now() + ttlMs });
1668
+ force((n) => n + 1);
1669
+ });
1670
+ return off;
1671
+ }, [screenId, ttlMs]);
1672
+ react.useEffect(() => {
1673
+ const t = window.setInterval(() => {
1674
+ const now = Date.now();
1675
+ let dirty = false;
1676
+ for (const [k, v] of hitsRef.current) {
1677
+ if (v.expiresAt < now) {
1678
+ hitsRef.current.delete(k);
1679
+ dirty = true;
1680
+ }
1681
+ }
1682
+ if (dirty) force((n) => n + 1);
1683
+ }, 500);
1684
+ return () => window.clearInterval(t);
1685
+ }, []);
1686
+ const out = {};
1687
+ for (const [elementId, { event }] of hitsRef.current) {
1688
+ const idx = elementId.indexOf("!");
1689
+ const address = elementId.slice(idx + 1);
1690
+ if (!address) continue;
1691
+ const color = event.agentColor ?? "#a855f7";
1692
+ out[address] = {
1693
+ color,
1694
+ background: color + "33",
1695
+ label: event.agentName ?? event.agentId ?? "agent"
1696
+ };
1697
+ }
1698
+ return out;
1699
+ }
1700
+
1594
1701
  // src/bridges/code.ts
1595
1702
  var DEFAULT_AGENT5 = { id: "agent", name: "Agent", color: "#a855f7" };
1596
- function registerCodeBridge(server, options) {
1703
+ function registerCodeBridge(host, options) {
1597
1704
  const { adapter } = options;
1598
1705
  const agent = { ...DEFAULT_AGENT5, ...options.agent ?? {} };
1599
1706
  const disposers = [];
@@ -1619,7 +1726,7 @@ function registerCodeBridge(server, options) {
1619
1726
  resolveTarget: () => target
1620
1727
  }) : wrapped;
1621
1728
  disposers.push(
1622
- server.registerTool(
1729
+ host.registerTool(
1623
1730
  {
1624
1731
  name,
1625
1732
  description,
@@ -1759,7 +1866,7 @@ function registerCodeBridge(server, options) {
1759
1866
 
1760
1867
  // src/bridges/charts.ts
1761
1868
  var DEFAULT_AGENT6 = { id: "agent", name: "Agent", color: "#a855f7" };
1762
- function registerChartsBridge(server, options) {
1869
+ function registerChartsBridge(host, options) {
1763
1870
  const { adapter } = options;
1764
1871
  const agent = { ...DEFAULT_AGENT6, ...options.agent ?? {} };
1765
1872
  const disposers = [];
@@ -1785,7 +1892,7 @@ function registerChartsBridge(server, options) {
1785
1892
  resolveTarget: () => target
1786
1893
  }) : wrapped;
1787
1894
  disposers.push(
1788
- server.registerTool(
1895
+ host.registerTool(
1789
1896
  { name, description, inputSchema: { type: "object", properties, required, additionalProperties: false } },
1790
1897
  final
1791
1898
  )
@@ -1873,7 +1980,7 @@ function registerChartsBridge(server, options) {
1873
1980
 
1874
1981
  // src/bridges/scene.ts
1875
1982
  var DEFAULT_AGENT7 = { id: "agent", name: "Agent", color: "#a855f7" };
1876
- function registerSceneBridge(server, options) {
1983
+ function registerSceneBridge(host, options) {
1877
1984
  const { adapter } = options;
1878
1985
  const agent = { ...DEFAULT_AGENT7, ...options.agent ?? {} };
1879
1986
  const disposers = [];
@@ -1899,7 +2006,7 @@ function registerSceneBridge(server, options) {
1899
2006
  resolveTarget: ({ args }) => target(objectIdFromArgs?.(args))
1900
2007
  }) : wrapped;
1901
2008
  disposers.push(
1902
- server.registerTool(
2009
+ host.registerTool(
1903
2010
  { name, description, inputSchema: { type: "object", properties, required, additionalProperties: false } },
1904
2011
  final
1905
2012
  )
@@ -2067,6 +2174,180 @@ function parseTriple(v) {
2067
2174
  if (out.some((x) => !Number.isFinite(x))) return void 0;
2068
2175
  return out;
2069
2176
  }
2177
+
2178
+ // src/bridges/screens.ts
2179
+ var DEFAULT_AGENT8 = { id: "agent", name: "Agent", color: "#a855f7" };
2180
+ function registerScreensBridge(host, options) {
2181
+ const { adapter } = options;
2182
+ const agent = { ...DEFAULT_AGENT8, ...options.agent ?? {} };
2183
+ const disposers = [];
2184
+ const target = (screenId) => ({
2185
+ kind: "screens",
2186
+ screenId,
2187
+ label: `Screen ${screenId}`
2188
+ });
2189
+ const reg = (name, description, properties, required, handler, isMutation, targetFromArgs) => {
2190
+ const wrapped = async (args) => {
2191
+ try {
2192
+ return await handler(args);
2193
+ } catch (e) {
2194
+ return errorResult(e instanceof Error ? e.message : String(e));
2195
+ }
2196
+ };
2197
+ const final = isMutation ? wrapToolWithActivity(wrapped, {
2198
+ toolName: name,
2199
+ agent,
2200
+ kind: "screens",
2201
+ resolveTarget: ({ args }) => targetFromArgs?.(args) ?? null
2202
+ }) : wrapped;
2203
+ disposers.push(
2204
+ host.registerTool(
2205
+ { name, description, inputSchema: { type: "object", properties, required, additionalProperties: false } },
2206
+ final
2207
+ )
2208
+ );
2209
+ };
2210
+ reg(
2211
+ "screens_list",
2212
+ "List every screen the host has registered. Returns id, title, active flag, and optional kind.",
2213
+ {},
2214
+ [],
2215
+ () => {
2216
+ const screens = adapter.listScreens();
2217
+ const text = screens.map((s) => `${s.active ? "\u25B8" : " "} ${s.id}${s.title ? ` \u2014 ${s.title}` : ""}${s.kind ? ` [${s.kind}]` : ""}`).join("\n");
2218
+ return textResult(text || "(no screens)", { screens, active: adapter.getActive() });
2219
+ },
2220
+ false
2221
+ );
2222
+ reg(
2223
+ "screens_describe_active",
2224
+ "Get the currently-active screen id (or null).",
2225
+ {},
2226
+ [],
2227
+ () => {
2228
+ const active = adapter.getActive();
2229
+ return textResult(active ?? "(none)", { active });
2230
+ },
2231
+ false
2232
+ );
2233
+ reg(
2234
+ "screens_list_kinds",
2235
+ "List the screen kinds (templates) the host knows how to instantiate. Use this before screens_create to know what's available.",
2236
+ {},
2237
+ [],
2238
+ () => {
2239
+ if (!adapter.listKinds) return errorResult("Host did not register a kind catalog. Cannot create screens dynamically.");
2240
+ const kinds = adapter.listKinds();
2241
+ const text = kinds.map((k) => `${k.kind}${k.label ? ` \u2014 ${k.label}` : ""}${k.description ? ` (${k.description})` : ""}`).join("\n");
2242
+ return textResult(text || "(no kinds registered)", kinds);
2243
+ },
2244
+ false
2245
+ );
2246
+ reg(
2247
+ "screens_create",
2248
+ "Instantiate a new screen from a template kind + config. Switches the active view to the new screen.",
2249
+ {
2250
+ id: { type: "string", description: "Stable screen id. Must be unique." },
2251
+ title: { type: "string" },
2252
+ kind: { type: "string", description: "Template kind \u2014 call screens_list_kinds for the catalog." },
2253
+ config: { type: "object", description: "Template-specific config (e.g. { fields: [...] } for a form)." }
2254
+ },
2255
+ ["id", "kind"],
2256
+ (args) => {
2257
+ if (!adapter.createScreen) return errorResult("Host did not provide createScreen.");
2258
+ const id = String(args.id);
2259
+ const kind = String(args.kind);
2260
+ if (adapter.listScreens().find((s) => s.id === id)) {
2261
+ return errorResult(`Screen ${id} already exists. Use screens_destroy first or pick a fresh id.`);
2262
+ }
2263
+ adapter.createScreen({
2264
+ id,
2265
+ title: typeof args.title === "string" ? args.title : void 0,
2266
+ kind,
2267
+ config: args.config && typeof args.config === "object" ? args.config : void 0
2268
+ });
2269
+ adapter.setActive(id);
2270
+ return textResult(`Created ${kind} screen "${id}"`, { id, kind });
2271
+ },
2272
+ true,
2273
+ (args) => target(String(args.id ?? ""))
2274
+ );
2275
+ reg(
2276
+ "screens_destroy",
2277
+ "Remove a previously-created screen. Active screen falls back to the first remaining one (or null).",
2278
+ { id: { type: "string" } },
2279
+ ["id"],
2280
+ (args) => {
2281
+ if (!adapter.destroyScreen) return errorResult("Host did not provide destroyScreen.");
2282
+ const id = String(args.id);
2283
+ if (!adapter.listScreens().find((s) => s.id === id)) {
2284
+ return errorResult(`No screen with id ${id}`);
2285
+ }
2286
+ adapter.destroyScreen(id);
2287
+ return textResult(`Destroyed screen ${id}`, { id });
2288
+ },
2289
+ true,
2290
+ (args) => target(String(args.id ?? ""))
2291
+ );
2292
+ reg(
2293
+ "screens_set_layout",
2294
+ "Change the layout of an existing composite screen. Layouts: 'single', 'split-h' (left/right), 'split-v' (top/bottom), 'grid-2x2', 'stack' (tabs).",
2295
+ {
2296
+ id: { type: "string" },
2297
+ layout: { type: "string", enum: ["single", "split-h", "split-v", "grid-2x2", "stack"] }
2298
+ },
2299
+ ["id", "layout"],
2300
+ (args) => {
2301
+ if (!adapter.updateScreenContent) return errorResult("Host did not provide updateScreenContent.");
2302
+ adapter.updateScreenContent(String(args.id), { layout: String(args.layout) });
2303
+ return textResult(`Layout of ${args.id} \u2192 ${args.layout}`, { id: args.id, layout: args.layout });
2304
+ },
2305
+ true,
2306
+ (args) => target(String(args.id ?? ""))
2307
+ );
2308
+ reg(
2309
+ "screens_update_content",
2310
+ "Merge new config into an existing screen (e.g. add a field to a form, append a sheet column, change chart series).",
2311
+ {
2312
+ id: { type: "string" },
2313
+ partial: { type: "object", description: "Shallow-merged into the screen's config." }
2314
+ },
2315
+ ["id", "partial"],
2316
+ (args) => {
2317
+ if (!adapter.updateScreenContent) return errorResult("Host did not provide updateScreenContent.");
2318
+ const id = String(args.id);
2319
+ const partial = args.partial && typeof args.partial === "object" ? args.partial : {};
2320
+ adapter.updateScreenContent(id, partial);
2321
+ return textResult(`Updated content of ${id}`, { id });
2322
+ },
2323
+ true,
2324
+ (args) => target(String(args.id ?? ""))
2325
+ );
2326
+ reg(
2327
+ "screens_navigate",
2328
+ "Switch the human's view to a different screen. The host updates its router / tab state and re-renders.",
2329
+ { screen: { type: "string", description: "Screen id to activate." } },
2330
+ ["screen"],
2331
+ (args) => {
2332
+ const screenId = String(args.screen ?? "");
2333
+ const screens = adapter.listScreens();
2334
+ if (!screens.find((s) => s.id === screenId)) {
2335
+ return errorResult(`No screen registered with id "${screenId}". Call screens_list first.`);
2336
+ }
2337
+ adapter.setActive(screenId);
2338
+ return textResult(`Navigated to ${screenId}`, { screen: screenId });
2339
+ },
2340
+ true,
2341
+ (args) => target(String(args.screen ?? ""))
2342
+ );
2343
+ return {
2344
+ id: "screens",
2345
+ title: "Screens",
2346
+ dispose: () => {
2347
+ for (const d of disposers) d();
2348
+ }
2349
+ };
2350
+ }
2070
2351
  function AgentPanel({ agent, activity, onSubmit, busy, actions, className, style }) {
2071
2352
  const scrollRef = react.useRef(null);
2072
2353
  const inputRef = react.useRef(null);
@@ -2612,14 +2893,14 @@ function attachSseRelay(server, options) {
2612
2893
  });
2613
2894
  return transport;
2614
2895
  }
2615
- var DEFAULT_AGENT8 = { id: "agent", name: "Agent", color: "#a855f7" };
2896
+ var DEFAULT_AGENT9 = { id: "agent", name: "Agent", color: "#a855f7" };
2616
2897
  function SharedWhiteboard({
2617
2898
  initialNotes = [],
2618
2899
  initialShapes = [],
2619
2900
  initialConnectors = [],
2620
2901
  initialStrokes = [],
2621
2902
  initialViewport = { x: 0, y: 0, zoom: 1 },
2622
- agent = DEFAULT_AGENT8,
2903
+ agent = DEFAULT_AGENT9,
2623
2904
  shareBaseUrl = "/whiteboard-share",
2624
2905
  onRegisterSession,
2625
2906
  showAgentPanel = true,
@@ -2948,6 +3229,7 @@ exports.ScreensActivityBridge = ScreensActivityBridge;
2948
3229
  exports.ShareControls = ShareControls;
2949
3230
  exports.SharedWhiteboard = SharedWhiteboard;
2950
3231
  exports.SseRelayTransport = SseRelayTransport;
3232
+ exports.ToolRegistry = ToolRegistry;
2951
3233
  exports.attachInProcess = attachInProcess;
2952
3234
  exports.attachRelay = attachRelay;
2953
3235
  exports.attachSseRelay = attachSseRelay;
@@ -2970,6 +3252,7 @@ exports.registerCodeBridge = registerCodeBridge;
2970
3252
  exports.registerFlowBridge = registerFlowBridge;
2971
3253
  exports.registerFormBridge = registerFormBridge;
2972
3254
  exports.registerSceneBridge = registerSceneBridge;
3255
+ exports.registerScreensBridge = registerScreensBridge;
2973
3256
  exports.registerSheetsBridge = registerSheetsBridge;
2974
3257
  exports.registerUndoTools = registerUndoTools;
2975
3258
  exports.registerWhiteboardBridge = registerWhiteboardBridge;
@@ -2980,6 +3263,8 @@ exports.textResult = textResult;
2980
3263
  exports.undoOne = undoOne;
2981
3264
  exports.useAgentActivity = useAgentActivity;
2982
3265
  exports.useAgentActivityForScreen = useAgentActivityForScreen;
3266
+ exports.useSheetsActivityHighlights = useSheetsActivityHighlights;
3267
+ exports.useSheetsAdapter = useSheetsAdapter;
2983
3268
  exports.useUndoStack = useUndoStack;
2984
3269
  exports.wrapToolWithActivity = wrapToolWithActivity;
2985
3270
  //# sourceMappingURL=index.cjs.map