@particle-academy/agent-integrations 0.25.0 → 0.27.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 (141) hide show
  1. package/dist/bridges/artboard.d.cts +3 -3
  2. package/dist/bridges/artboard.d.ts +3 -3
  3. package/dist/bridges/catalog.d.cts +3 -3
  4. package/dist/bridges/catalog.d.ts +3 -3
  5. package/dist/bridges/charts.d.cts +3 -3
  6. package/dist/bridges/charts.d.ts +3 -3
  7. package/dist/bridges/cms.d.cts +50 -0
  8. package/dist/bridges/cms.d.ts +50 -0
  9. package/dist/bridges/code.d.cts +3 -3
  10. package/dist/bridges/code.d.ts +3 -3
  11. package/dist/bridges/doc.d.cts +68 -0
  12. package/dist/bridges/doc.d.ts +68 -0
  13. package/dist/bridges/features.d.cts +3 -3
  14. package/dist/bridges/features.d.ts +3 -3
  15. package/dist/bridges/files.d.cts +3 -3
  16. package/dist/bridges/files.d.ts +3 -3
  17. package/dist/bridges/flow.d.cts +3 -3
  18. package/dist/bridges/flow.d.ts +3 -3
  19. package/dist/bridges/forms.d.cts +3 -3
  20. package/dist/bridges/forms.d.ts +3 -3
  21. package/dist/bridges/map.d.cts +3 -3
  22. package/dist/bridges/map.d.ts +3 -3
  23. package/dist/bridges/scene.d.cts +3 -3
  24. package/dist/bridges/scene.d.ts +3 -3
  25. package/dist/bridges/screens.d.cts +3 -3
  26. package/dist/bridges/screens.d.ts +3 -3
  27. package/dist/bridges/sheets.d.cts +3 -3
  28. package/dist/bridges/sheets.d.ts +3 -3
  29. package/dist/bridges/slides.d.cts +3 -3
  30. package/dist/bridges/slides.d.ts +3 -3
  31. package/dist/bridges/terminal.d.cts +3 -3
  32. package/dist/bridges/terminal.d.ts +3 -3
  33. package/dist/bridges/whiteboard.d.cts +3 -3
  34. package/dist/bridges/whiteboard.d.ts +3 -3
  35. package/dist/bridges-artboard.js +1 -1
  36. package/dist/bridges-catalog.js +2 -2
  37. package/dist/bridges-charts.cjs +77 -0
  38. package/dist/bridges-charts.cjs.map +1 -1
  39. package/dist/bridges-charts.js +2 -1
  40. package/dist/bridges-cms.cjs +437 -0
  41. package/dist/bridges-cms.cjs.map +1 -0
  42. package/dist/bridges-cms.js +8 -0
  43. package/dist/bridges-cms.js.map +1 -0
  44. package/dist/bridges-code.cjs +77 -0
  45. package/dist/bridges-code.cjs.map +1 -1
  46. package/dist/bridges-code.js +2 -1
  47. package/dist/bridges-doc.cjs +364 -0
  48. package/dist/bridges-doc.cjs.map +1 -0
  49. package/dist/bridges-doc.js +7 -0
  50. package/dist/bridges-doc.js.map +1 -0
  51. package/dist/bridges-features.js +2 -2
  52. package/dist/bridges-files.cjs +1 -1
  53. package/dist/bridges-files.cjs.map +1 -1
  54. package/dist/bridges-files.js +2 -2
  55. package/dist/bridges-flow.cjs +77 -0
  56. package/dist/bridges-flow.cjs.map +1 -1
  57. package/dist/bridges-flow.js +2 -0
  58. package/dist/bridges-flow.js.map +1 -1
  59. package/dist/bridges-forms.cjs +77 -0
  60. package/dist/bridges-forms.cjs.map +1 -1
  61. package/dist/bridges-forms.js +2 -1
  62. package/dist/bridges-map.cjs +1 -1
  63. package/dist/bridges-map.cjs.map +1 -1
  64. package/dist/bridges-map.js +2 -2
  65. package/dist/bridges-scene.cjs +77 -0
  66. package/dist/bridges-scene.cjs.map +1 -1
  67. package/dist/bridges-scene.js +2 -1
  68. package/dist/bridges-screens.cjs +77 -0
  69. package/dist/bridges-screens.cjs.map +1 -1
  70. package/dist/bridges-screens.js +2 -1
  71. package/dist/bridges-sheets.cjs +77 -0
  72. package/dist/bridges-sheets.cjs.map +1 -1
  73. package/dist/bridges-sheets.js +2 -1
  74. package/dist/bridges-slides.cjs +77 -0
  75. package/dist/bridges-slides.cjs.map +1 -1
  76. package/dist/bridges-slides.js +2 -1
  77. package/dist/bridges-terminal.js +2 -2
  78. package/dist/bridges-whiteboard.js +2 -2
  79. package/dist/{chunk-CKK4QKD2.js → chunk-66WOHZZJ.js} +4 -2
  80. package/dist/chunk-66WOHZZJ.js.map +1 -0
  81. package/dist/chunk-A57CRGEK.js +79 -0
  82. package/dist/chunk-A57CRGEK.js.map +1 -0
  83. package/dist/{chunk-XQZGB4FP.js → chunk-AAD3Z5E7.js} +3 -3
  84. package/dist/{chunk-XQZGB4FP.js.map → chunk-AAD3Z5E7.js.map} +1 -1
  85. package/dist/{chunk-3QJSOS7G.js → chunk-AAMQOXZC.js} +3 -3
  86. package/dist/{chunk-3QJSOS7G.js.map → chunk-AAMQOXZC.js.map} +1 -1
  87. package/dist/{chunk-SJ7H242B.js → chunk-AROVENCE.js} +4 -2
  88. package/dist/chunk-AROVENCE.js.map +1 -0
  89. package/dist/chunk-FF5F526J.js +245 -0
  90. package/dist/chunk-FF5F526J.js.map +1 -0
  91. package/dist/{chunk-57KAMBAR.js → chunk-HWVVS6HE.js} +3 -3
  92. package/dist/{chunk-57KAMBAR.js.map → chunk-HWVVS6HE.js.map} +1 -1
  93. package/dist/{chunk-FYGMFIY5.js → chunk-NN3ELTVO.js} +4 -2
  94. package/dist/chunk-NN3ELTVO.js.map +1 -0
  95. package/dist/{chunk-5AD35HS5.js → chunk-PCW2EK5G.js} +4 -2
  96. package/dist/chunk-PCW2EK5G.js.map +1 -0
  97. package/dist/{chunk-DR7X4TWE.js → chunk-QDD4WHIV.js} +4 -2
  98. package/dist/chunk-QDD4WHIV.js.map +1 -0
  99. package/dist/{chunk-HIMTURWL.js → chunk-QRDVJW6Q.js} +4 -2
  100. package/dist/chunk-QRDVJW6Q.js.map +1 -0
  101. package/dist/{chunk-267JS64O.js → chunk-VFKO2VUR.js} +3 -3
  102. package/dist/{chunk-267JS64O.js.map → chunk-VFKO2VUR.js.map} +1 -1
  103. package/dist/{chunk-UOMSY7MZ.js → chunk-XMMCSQ4I.js} +4 -4
  104. package/dist/{chunk-UOMSY7MZ.js.map → chunk-XMMCSQ4I.js.map} +1 -1
  105. package/dist/{chunk-VUMFO2UW.js → chunk-YGD2VTUM.js} +4 -2
  106. package/dist/chunk-YGD2VTUM.js.map +1 -0
  107. package/dist/{chunk-3VRQGDKV.js → chunk-ZX6UQURN.js} +4 -4
  108. package/dist/{chunk-3VRQGDKV.js.map → chunk-ZX6UQURN.js.map} +1 -1
  109. package/dist/components-shared-whiteboard.js +2 -2
  110. package/dist/index.cjs +399 -80
  111. package/dist/index.cjs.map +1 -1
  112. package/dist/index.d.cts +10 -7
  113. package/dist/index.d.ts +10 -7
  114. package/dist/index.js +20 -18
  115. package/dist/index.js.map +1 -1
  116. package/dist/mcp/index.d.cts +5 -5
  117. package/dist/mcp/index.d.ts +5 -5
  118. package/dist/presence/index.d.cts +1 -1
  119. package/dist/presence/index.d.ts +1 -1
  120. package/dist/{server-BsSwfemr.d.cts → server-Dr3j48CU.d.cts} +2 -2
  121. package/dist/{server-Du3-IGqM.d.ts → server-FFZpYPyM.d.ts} +2 -2
  122. package/dist/sharing/index.d.cts +3 -3
  123. package/dist/sharing/index.d.ts +3 -3
  124. package/dist/sheets-adapter.d.cts +3 -3
  125. package/dist/sheets-adapter.d.ts +3 -3
  126. package/dist/{tool-host-C8JMMGYq.d.ts → tool-host-C_Vh17J_.d.ts} +1 -1
  127. package/dist/{tool-host-BQuUygLF.d.cts → tool-host-IDecPrF1.d.cts} +1 -1
  128. package/dist/{types-CCSBGW9T.d.cts → types-B0rmWyoR.d.cts} +1 -1
  129. package/dist/{types-aOQLTW0E.d.cts → types-BDI_g5UG.d.cts} +1 -1
  130. package/dist/{types-aOQLTW0E.d.ts → types-BDI_g5UG.d.ts} +1 -1
  131. package/dist/{types-DIVNcIQO.d.ts → types-CBoQhR8L.d.ts} +1 -1
  132. package/dist/undo/index.d.cts +2 -2
  133. package/dist/undo/index.d.ts +2 -2
  134. package/package.json +23 -2
  135. package/dist/chunk-5AD35HS5.js.map +0 -1
  136. package/dist/chunk-CKK4QKD2.js.map +0 -1
  137. package/dist/chunk-DR7X4TWE.js.map +0 -1
  138. package/dist/chunk-FYGMFIY5.js.map +0 -1
  139. package/dist/chunk-HIMTURWL.js.map +0 -1
  140. package/dist/chunk-SJ7H242B.js.map +0 -1
  141. package/dist/chunk-VUMFO2UW.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  var fancyAutoCommon = require('@particle-academy/fancy-auto-common');
4
4
  var react = require('react');
5
+ var fancyDocCommons = require('@particle-academy/fancy-doc-commons');
5
6
  var jsxRuntime = require('react/jsx-runtime');
6
7
  var reactDom = require('react-dom');
7
8
 
@@ -285,12 +286,89 @@ function extractMeta(result) {
285
286
  return void 0;
286
287
  }
287
288
 
289
+ // src/undo/undo-tools.ts
290
+ var installedHosts = /* @__PURE__ */ new WeakSet();
291
+ function ensureUndoToolsRegistered(host, options = {}) {
292
+ if (installedHosts.has(host)) return;
293
+ installedHosts.add(host);
294
+ registerUndoTools(host, options);
295
+ }
296
+ function registerUndoTools(host, options = {}) {
297
+ const defaultAgent = options.defaultAgentId ?? "agent";
298
+ const disposers = [];
299
+ const agentOf = (args) => typeof args?.agentId === "string" ? args.agentId : defaultAgent;
300
+ disposers.push(
301
+ host.registerTool(
302
+ {
303
+ name: "agent_undo",
304
+ description: "Undo the most recent action on the agent's stack. Optional agentId targets a specific agent.",
305
+ inputSchema: {
306
+ type: "object",
307
+ properties: { agentId: { type: "string" } },
308
+ additionalProperties: false
309
+ }
310
+ },
311
+ async (args) => {
312
+ const entry = await fancyAutoCommon.undoOne(agentOf(args));
313
+ if (!entry) return errorResult("Nothing to undo.");
314
+ return textResult(`Undid: ${entry.label}`, { entry: serialize(entry) });
315
+ }
316
+ )
317
+ );
318
+ disposers.push(
319
+ host.registerTool(
320
+ {
321
+ name: "agent_redo",
322
+ description: "Redo the most recently undone action.",
323
+ inputSchema: {
324
+ type: "object",
325
+ properties: { agentId: { type: "string" } },
326
+ additionalProperties: false
327
+ }
328
+ },
329
+ async (args) => {
330
+ const entry = await fancyAutoCommon.redoOne(agentOf(args));
331
+ if (!entry) return errorResult("Nothing to redo.");
332
+ return textResult(`Redid: ${entry.label}`, { entry: serialize(entry) });
333
+ }
334
+ )
335
+ );
336
+ disposers.push(
337
+ host.registerTool(
338
+ {
339
+ name: "agent_history",
340
+ description: "List the agent's undo stack (oldest first). Useful for understanding what's reversible.",
341
+ inputSchema: {
342
+ type: "object",
343
+ properties: { agentId: { type: "string" } },
344
+ additionalProperties: false
345
+ }
346
+ },
347
+ async (args) => {
348
+ const history = fancyAutoCommon.readHistory(agentOf(args)).map(serialize);
349
+ const text = history.map((e) => `${new Date(e.timestamp).toISOString()} ${e.bridgeId} ${e.action}: ${e.label}`).join("\n");
350
+ return textResult(text || "(empty)", history);
351
+ }
352
+ )
353
+ );
354
+ return () => disposers.forEach((d) => d());
355
+ }
356
+ function serialize(entry) {
357
+ return {
358
+ timestamp: entry.timestamp,
359
+ bridgeId: entry.bridgeId,
360
+ action: entry.action,
361
+ label: entry.label
362
+ };
363
+ }
364
+
288
365
  // src/bridges/forms.ts
289
366
  var DEFAULT_AGENT = { id: "agent", name: "Agent", color: "#a855f7" };
290
367
  function registerFormBridge(host, options) {
291
368
  const { adapter } = options;
292
369
  const agent = { ...DEFAULT_AGENT, ...options.agent ?? {} };
293
370
  const disposers = [];
371
+ ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
294
372
  const formId = adapter.id;
295
373
  const target = (args) => ({
296
374
  kind: "form",
@@ -443,6 +521,7 @@ function registerSheetsBridge(host, options) {
443
521
  const { adapter } = options;
444
522
  const agent = { ...DEFAULT_AGENT2, ...options.agent ?? {} };
445
523
  const disposers = [];
524
+ ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
446
525
  const target = (sheetId, address) => ({
447
526
  kind: "sheet",
448
527
  screenId: adapter.screenId,
@@ -789,6 +868,7 @@ function registerCodeBridge(host, options) {
789
868
  const { adapter } = options;
790
869
  const agent = { ...DEFAULT_AGENT3, ...options.agent ?? {} };
791
870
  const disposers = [];
871
+ ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
792
872
  const target = {
793
873
  kind: "code",
794
874
  screenId: adapter.screenId,
@@ -955,6 +1035,7 @@ function registerChartsBridge(host, options) {
955
1035
  const { adapter } = options;
956
1036
  const agent = { ...DEFAULT_AGENT4, ...options.agent ?? {} };
957
1037
  const disposers = [];
1038
+ ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
958
1039
  const target = {
959
1040
  kind: "chart",
960
1041
  screenId: adapter.screenId,
@@ -1069,6 +1150,7 @@ function registerSceneBridge(host, options) {
1069
1150
  const { adapter } = options;
1070
1151
  const agent = { ...DEFAULT_AGENT5, ...options.agent ?? {} };
1071
1152
  const disposers = [];
1153
+ ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
1072
1154
  const target = (objectId) => ({
1073
1155
  kind: "scene",
1074
1156
  screenId: adapter.screenId,
@@ -1266,6 +1348,7 @@ function registerScreensBridge(host, options) {
1266
1348
  const { adapter } = options;
1267
1349
  const agent = { ...DEFAULT_AGENT6, ...options.agent ?? {} };
1268
1350
  const disposers = [];
1351
+ ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
1269
1352
  const target = (screenId) => ({
1270
1353
  kind: "screens",
1271
1354
  screenId,
@@ -1440,6 +1523,7 @@ function registerSlidesBridge(host, options) {
1440
1523
  const { adapter } = options;
1441
1524
  const agent = { ...DEFAULT_AGENT7, ...options.agent ?? {} };
1442
1525
  const disposers = [];
1526
+ ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
1443
1527
  const deckTarget = () => ({
1444
1528
  kind: "deck",
1445
1529
  screenId: adapter.screenId,
@@ -1876,84 +1960,8 @@ function firstTextContent(slide) {
1876
1960
  return void 0;
1877
1961
  }
1878
1962
 
1879
- // src/undo/undo-tools.ts
1880
- var installedHosts = /* @__PURE__ */ new WeakSet();
1881
- function ensureUndoToolsRegistered(host, options = {}) {
1882
- if (installedHosts.has(host)) return;
1883
- installedHosts.add(host);
1884
- registerUndoTools(host, options);
1885
- }
1886
- function registerUndoTools(host, options = {}) {
1887
- const defaultAgent = options.defaultAgentId ?? "agent";
1888
- const disposers = [];
1889
- const agentOf = (args) => typeof args?.agentId === "string" ? args.agentId : defaultAgent;
1890
- disposers.push(
1891
- host.registerTool(
1892
- {
1893
- name: "agent_undo",
1894
- description: "Undo the most recent action on the agent's stack. Optional agentId targets a specific agent.",
1895
- inputSchema: {
1896
- type: "object",
1897
- properties: { agentId: { type: "string" } },
1898
- additionalProperties: false
1899
- }
1900
- },
1901
- async (args) => {
1902
- const entry = await fancyAutoCommon.undoOne(agentOf(args));
1903
- if (!entry) return errorResult("Nothing to undo.");
1904
- return textResult(`Undid: ${entry.label}`, { entry: serialize(entry) });
1905
- }
1906
- )
1907
- );
1908
- disposers.push(
1909
- host.registerTool(
1910
- {
1911
- name: "agent_redo",
1912
- description: "Redo the most recently undone action.",
1913
- inputSchema: {
1914
- type: "object",
1915
- properties: { agentId: { type: "string" } },
1916
- additionalProperties: false
1917
- }
1918
- },
1919
- async (args) => {
1920
- const entry = await fancyAutoCommon.redoOne(agentOf(args));
1921
- if (!entry) return errorResult("Nothing to redo.");
1922
- return textResult(`Redid: ${entry.label}`, { entry: serialize(entry) });
1923
- }
1924
- )
1925
- );
1926
- disposers.push(
1927
- host.registerTool(
1928
- {
1929
- name: "agent_history",
1930
- description: "List the agent's undo stack (oldest first). Useful for understanding what's reversible.",
1931
- inputSchema: {
1932
- type: "object",
1933
- properties: { agentId: { type: "string" } },
1934
- additionalProperties: false
1935
- }
1936
- },
1937
- async (args) => {
1938
- const history = fancyAutoCommon.readHistory(agentOf(args)).map(serialize);
1939
- const text = history.map((e) => `${new Date(e.timestamp).toISOString()} ${e.bridgeId} ${e.action}: ${e.label}`).join("\n");
1940
- return textResult(text || "(empty)", history);
1941
- }
1942
- )
1943
- );
1944
- return () => disposers.forEach((d) => d());
1945
- }
1946
- function serialize(entry) {
1947
- return {
1948
- timestamp: entry.timestamp,
1949
- bridgeId: entry.bridgeId,
1950
- action: entry.action,
1951
- label: entry.label
1952
- };
1953
- }
1954
-
1955
1963
  // src/bridges/map.ts
1956
- var DEFAULT_AGENT8 = { id: "agent", name: "Agent", color: "#7c3aed" };
1964
+ var DEFAULT_AGENT8 = { id: "agent", name: "Agent", color: "#a855f7" };
1957
1965
  var num2 = (v, fallback) => typeof v === "number" && Number.isFinite(v) ? v : 0;
1958
1966
  var str2 = (v, fallback = "") => typeof v === "string" ? v : fallback;
1959
1967
  var newId = (prefix) => `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`;
@@ -2280,7 +2288,7 @@ function registerMapBridge(host, options) {
2280
2288
  }
2281
2289
 
2282
2290
  // src/bridges/files.ts
2283
- var DEFAULT_AGENT9 = { id: "agent", name: "Agent", color: "#0ea5e9" };
2291
+ var DEFAULT_AGENT9 = { id: "agent", name: "Agent", color: "#a855f7" };
2284
2292
  var str3 = (v, fallback = "") => typeof v === "string" ? v : fallback;
2285
2293
  var num3 = (v, fallback) => typeof v === "number" && Number.isFinite(v) ? v : 0;
2286
2294
  var asPaths = (v) => {
@@ -3479,6 +3487,314 @@ function registerFeaturesBridge(host, options) {
3479
3487
  }
3480
3488
  };
3481
3489
  }
3490
+ var DEFAULT_AGENT14 = { id: "agent", name: "Agent", color: "#a855f7" };
3491
+ function registerDocBridge(host, options) {
3492
+ const { adapter, surface } = options;
3493
+ const agent = { ...DEFAULT_AGENT14, ...options.agent ?? {} };
3494
+ const reducer = options.reducer ?? fancyDocCommons.treeReducer();
3495
+ const stage = options.stagePolicy ?? fancyDocCommons.autoApply;
3496
+ const makeNode = options.makeNode ?? (({ id, type, parent, order }, props) => ({ id, type, parent, order, props }));
3497
+ const describeNode = options.describeNode ?? ((n) => ({ id: n.id, type: n.type, parent: n.parent, props: Object.keys(n.props ?? {}) }));
3498
+ const disposers = [];
3499
+ ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
3500
+ let idSeq = 0;
3501
+ const mintId = () => adapter.newId?.() ?? `${surface}-${idSeq += 1}`;
3502
+ const target = (elementId) => ({ kind: surface, screenId: adapter.screenId, elementId });
3503
+ const pending = /* @__PURE__ */ new Map();
3504
+ function commit(op, label, targetId) {
3505
+ const prev = adapter.get();
3506
+ const next = reducer.reduce(prev, op);
3507
+ adapter.set(next);
3508
+ fancyAutoCommon.pushUndoEntry(agent.id, {
3509
+ timestamp: Date.now(),
3510
+ bridgeId: surface,
3511
+ action: label,
3512
+ label,
3513
+ undo: () => adapter.set(prev),
3514
+ redo: () => adapter.set(next)
3515
+ });
3516
+ return { ok: true, id: targetId };
3517
+ }
3518
+ function submit(op, label, targetId) {
3519
+ if (stage(op) === "confirm") {
3520
+ const id = `${surface}-pending-${idSeq += 1}`;
3521
+ pending.set(id, { op, label, targetId });
3522
+ options.onPending?.({ id, op, label });
3523
+ return { staged: true, id };
3524
+ }
3525
+ commit(op, label, targetId);
3526
+ return { staged: false, id: targetId };
3527
+ }
3528
+ const reg = (verb, description, properties, required, handler, isMutation, resolveTarget) => {
3529
+ const name = `${surface}_${verb}`;
3530
+ const wrapped = async (args) => {
3531
+ try {
3532
+ const { _text, ...structured } = await handler(args);
3533
+ return textResult(typeof _text === "string" ? _text : name, structured);
3534
+ } catch (e) {
3535
+ return errorResult(e instanceof Error ? e.message : String(e));
3536
+ }
3537
+ };
3538
+ const final = isMutation ? wrapToolWithActivity(wrapped, {
3539
+ toolName: name,
3540
+ agent,
3541
+ kind: surface,
3542
+ screenId: adapter.screenId,
3543
+ resolveTarget: ({ args, result }) => {
3544
+ if (result.structuredContent?.staged) return null;
3545
+ return resolveTarget?.(args, result.structuredContent ?? {}) ?? target();
3546
+ }
3547
+ }) : wrapped;
3548
+ disposers.push(
3549
+ host.registerTool(
3550
+ { name, description, inputSchema: { type: "object", properties, required, additionalProperties: false } },
3551
+ final
3552
+ )
3553
+ );
3554
+ };
3555
+ reg(
3556
+ "describe",
3557
+ `Summarize the ${surface} document: node count, roots, and the active surface. Call before reading or writing.`,
3558
+ {},
3559
+ [],
3560
+ () => {
3561
+ const tree = adapter.get();
3562
+ const ids = Object.keys(tree.nodes);
3563
+ return { nodeCount: ids.length, roots: fancyDocCommons.childrenOf(tree, null).map((n) => n.id), _text: `${ids.length} nodes` };
3564
+ },
3565
+ false
3566
+ );
3567
+ reg(
3568
+ "get",
3569
+ `Get the whole ${surface} document tree as JSON.`,
3570
+ {},
3571
+ [],
3572
+ () => ({ tree: adapter.get(), _text: "full tree" }),
3573
+ false
3574
+ );
3575
+ reg(
3576
+ "list",
3577
+ "List nodes (optionally the children of `parent`), in order.",
3578
+ { parent: { type: ["string", "null"], description: "Parent id, or null/omitted for roots." } },
3579
+ [],
3580
+ (args) => {
3581
+ const tree = adapter.get();
3582
+ const parent = typeof args.parent === "string" ? args.parent : null;
3583
+ return { nodes: fancyDocCommons.childrenOf(tree, parent).map(describeNode), _text: `children of ${parent ?? "root"}` };
3584
+ },
3585
+ false
3586
+ );
3587
+ reg(
3588
+ "get_node",
3589
+ "Get one node by id.",
3590
+ { id: { type: "string" } },
3591
+ ["id"],
3592
+ (args) => {
3593
+ const node = adapter.get().nodes[String(args.id)];
3594
+ if (!node) throw new Error(`No node ${args.id}`);
3595
+ return { node, _text: `node ${node.id}` };
3596
+ },
3597
+ false
3598
+ );
3599
+ reg(
3600
+ "add",
3601
+ "Insert a node. Returns its id. Appends under `parent` (or roots) unless `order` is given.",
3602
+ {
3603
+ type: { type: "string", description: "Node type discriminant." },
3604
+ parent: { type: ["string", "null"], description: "Parent id, or null for a root." },
3605
+ props: { type: "object", description: "JSON props bag." },
3606
+ order: { type: "string", description: "Fractional order key (default: append)." }
3607
+ },
3608
+ ["type"],
3609
+ (args) => {
3610
+ const tree = adapter.get();
3611
+ const parent = typeof args.parent === "string" ? args.parent : null;
3612
+ const id = mintId();
3613
+ const order = typeof args.order === "string" ? args.order : fancyDocCommons.appendOrder(tree, parent);
3614
+ const props = args.props && typeof args.props === "object" ? args.props : {};
3615
+ const node = makeNode({ id, type: String(args.type), parent, order }, props);
3616
+ const res = submit({ t: "insert", node }, `add ${args.type} ${id}`, id);
3617
+ return { ...res, _text: res.staged ? `staged add ${id}` : `added ${id}` };
3618
+ },
3619
+ true,
3620
+ (_args, result) => target(result.id)
3621
+ );
3622
+ reg(
3623
+ "update",
3624
+ "Merge a props patch into a node.",
3625
+ { id: { type: "string" }, patch: { type: "object" } },
3626
+ ["id", "patch"],
3627
+ (args) => {
3628
+ const id = String(args.id);
3629
+ if (!adapter.get().nodes[id]) throw new Error(`No node ${id}`);
3630
+ const patch = args.patch && typeof args.patch === "object" ? args.patch : {};
3631
+ const res = submit({ t: "set_props", id, patch }, `update ${id}`, id);
3632
+ return { ...res, id, _text: res.staged ? `staged update ${id}` : `updated ${id}` };
3633
+ },
3634
+ true,
3635
+ (args) => target(String(args.id))
3636
+ );
3637
+ reg(
3638
+ "remove",
3639
+ "Remove a node and its subtree.",
3640
+ { id: { type: "string" } },
3641
+ ["id"],
3642
+ (args) => {
3643
+ const id = String(args.id);
3644
+ const tree = adapter.get();
3645
+ if (!tree.nodes[id]) throw new Error(`No node ${id}`);
3646
+ const count = fancyDocCommons.descendantsOf(tree, id).length + 1;
3647
+ const res = submit({ t: "remove", id }, `remove ${id} (${count} node${count === 1 ? "" : "s"})`, id);
3648
+ return { ...res, id, removed: count, _text: res.staged ? `staged remove ${id}` : `removed ${id}` };
3649
+ },
3650
+ true,
3651
+ (args) => target(String(args.id))
3652
+ );
3653
+ reg(
3654
+ "move",
3655
+ "Reparent + reorder a node.",
3656
+ { id: { type: "string" }, parent: { type: ["string", "null"] }, order: { type: "string", description: "Fractional order key (default: append under the new parent)." } },
3657
+ ["id"],
3658
+ (args) => {
3659
+ const id = String(args.id);
3660
+ const tree = adapter.get();
3661
+ if (!tree.nodes[id]) throw new Error(`No node ${id}`);
3662
+ const parent = args.parent === null ? null : typeof args.parent === "string" ? args.parent : tree.nodes[id].parent;
3663
+ const order = typeof args.order === "string" ? args.order : fancyDocCommons.appendOrder(tree, parent);
3664
+ const res = submit({ t: "move", id, parent, order }, `move ${id}`, id);
3665
+ return { ...res, id, _text: res.staged ? `staged move ${id}` : `moved ${id}` };
3666
+ },
3667
+ true,
3668
+ (args) => target(String(args.id))
3669
+ );
3670
+ for (const t of options.opTools ?? []) {
3671
+ reg(
3672
+ t.verb,
3673
+ t.description,
3674
+ t.properties,
3675
+ t.required,
3676
+ (args) => {
3677
+ const built = t.build(args, adapter.get());
3678
+ if (built && typeof built === "object" && "error" in built) throw new Error(built.error);
3679
+ const tid = t.targetId?.(args);
3680
+ const res = submit(built, `${t.verb} ${tid ?? ""}`.trim(), tid);
3681
+ return { ...res, id: tid, _text: res.staged ? `staged ${t.verb}` : t.verb };
3682
+ },
3683
+ true,
3684
+ (args) => target(t.targetId?.(args))
3685
+ );
3686
+ }
3687
+ reg(
3688
+ "confirm",
3689
+ "Apply a staged op by its pending id (from a staged mutation).",
3690
+ { id: { type: "string" } },
3691
+ ["id"],
3692
+ (args) => {
3693
+ const id = String(args.id);
3694
+ const p = pending.get(id);
3695
+ if (!p) throw new Error(`No pending op ${id}`);
3696
+ pending.delete(id);
3697
+ commit(p.op, p.label, p.targetId);
3698
+ return { ok: true, applied: p.label, id: p.targetId, _text: `applied ${p.label}` };
3699
+ },
3700
+ true,
3701
+ (_args, result) => target(result.id)
3702
+ );
3703
+ reg(
3704
+ "reject",
3705
+ "Discard a staged op by its pending id.",
3706
+ { id: { type: "string" } },
3707
+ ["id"],
3708
+ (args) => {
3709
+ const id = String(args.id);
3710
+ const p = pending.get(id);
3711
+ if (!p) throw new Error(`No pending op ${id}`);
3712
+ pending.delete(id);
3713
+ return { ok: true, rejected: p.label, _text: `rejected ${p.label}` };
3714
+ },
3715
+ false
3716
+ );
3717
+ return {
3718
+ id: surface,
3719
+ title: surface,
3720
+ dispose: () => {
3721
+ for (const d of disposers) d();
3722
+ pending.clear();
3723
+ }
3724
+ };
3725
+ }
3726
+ function cmsReducer() {
3727
+ const base = fancyDocCommons.treeReducer();
3728
+ return {
3729
+ reduce(doc, op) {
3730
+ if (op.t === "set_style") {
3731
+ const node = doc.nodes[op.id];
3732
+ if (!node) return doc;
3733
+ return { nodes: { ...doc.nodes, [op.id]: { ...node, style: { ...node.style, base: { ...node.style.base, ...op.patch } } } } };
3734
+ }
3735
+ if (op.t === "set_layout") {
3736
+ const node = doc.nodes[op.id];
3737
+ if (!node) return doc;
3738
+ return { nodes: { ...doc.nodes, [op.id]: { ...node, layout: op.layout } } };
3739
+ }
3740
+ return base.reduce(doc, op);
3741
+ },
3742
+ invert(doc, op) {
3743
+ if (op.t === "set_style") {
3744
+ const node = doc.nodes[op.id];
3745
+ if (!node) return [];
3746
+ const prev = {};
3747
+ for (const k in op.patch) prev[k] = node.style.base[k];
3748
+ return [{ t: "set_style", id: op.id, patch: prev }];
3749
+ }
3750
+ if (op.t === "set_layout") {
3751
+ const node = doc.nodes[op.id];
3752
+ if (!node) return [];
3753
+ return [{ t: "set_layout", id: op.id, layout: node.layout }];
3754
+ }
3755
+ return base.invert(doc, op);
3756
+ }
3757
+ };
3758
+ }
3759
+ function registerCmsBridge(host, options) {
3760
+ return registerDocBridge(host, {
3761
+ adapter: options.adapter,
3762
+ surface: "cms",
3763
+ agent: options.agent,
3764
+ reducer: cmsReducer(),
3765
+ stagePolicy: options.stagePolicy,
3766
+ onPending: options.onPending,
3767
+ // New nodes get an empty base style so they satisfy StyledNode.
3768
+ makeNode: ({ id, type, parent, order }, props) => ({ id, type, parent, order, props, style: { base: {} } }),
3769
+ describeNode: (n) => ({ id: n.id, type: n.type, parent: n.parent, layout: n.layout }),
3770
+ opTools: [
3771
+ {
3772
+ verb: "set_style",
3773
+ description: "Merge a StyleProps patch into a node's base style (color, background, padding, fontSize, gap, \u2026).",
3774
+ properties: { id: { type: "string" }, patch: { type: "object", description: "Partial StyleProps." } },
3775
+ required: ["id", "patch"],
3776
+ build: (args, tree) => {
3777
+ const id = String(args.id);
3778
+ if (!tree.nodes[id]) return { error: `No node ${id}` };
3779
+ return { t: "set_style", id, patch: args.patch && typeof args.patch === "object" ? args.patch : {} };
3780
+ },
3781
+ targetId: (args) => String(args.id)
3782
+ },
3783
+ {
3784
+ verb: "set_layout",
3785
+ description: "Set a container node's layout mode (free | stack | grid).",
3786
+ properties: { id: { type: "string" }, layout: { type: "string", enum: ["free", "stack", "grid"] } },
3787
+ required: ["id"],
3788
+ build: (args, tree) => {
3789
+ const id = String(args.id);
3790
+ if (!tree.nodes[id]) return { error: `No node ${id}` };
3791
+ return { t: "set_layout", id, layout: args.layout };
3792
+ },
3793
+ targetId: (args) => String(args.id)
3794
+ }
3795
+ ]
3796
+ });
3797
+ }
3482
3798
 
3483
3799
  // src/sharing/token.ts
3484
3800
  var TOKEN_BYTES = 24;
@@ -3674,11 +3990,11 @@ function attachSseRelay(server, options) {
3674
3990
 
3675
3991
  // src/sharing/use-co-browse-session.ts
3676
3992
  init_registry();
3677
- var DEFAULT_AGENT14 = { id: "agent", name: "Agent", color: "#a855f7" };
3993
+ var DEFAULT_AGENT15 = { id: "agent", name: "Agent", color: "#a855f7" };
3678
3994
  var USER = { id: "human", name: "You" };
3679
3995
  function useCoBrowseSession(options) {
3680
3996
  const { adapter, extraBridges } = options;
3681
- const agent = { ...DEFAULT_AGENT14, ...options.agent ?? {} };
3997
+ const agent = { ...DEFAULT_AGENT15, ...options.agent ?? {} };
3682
3998
  const relayBaseUrl = options.relayBaseUrl ?? "/agent-relay";
3683
3999
  const serverRef = react.useRef(null);
3684
4000
  const relayRef = react.useRef(null);
@@ -4892,6 +5208,7 @@ exports.buildMcpbProxyStub = buildMcpbProxyStub;
4892
5208
  exports.buildShareConfig = buildShareConfig;
4893
5209
  exports.buildShareUrl = buildShareUrl;
4894
5210
  exports.buildVscodeDeeplink = buildVscodeDeeplink;
5211
+ exports.cmsReducer = cmsReducer;
4895
5212
  exports.connectorHref = connectorHref;
4896
5213
  exports.createSessionDescriptor = createSessionDescriptor;
4897
5214
  exports.describeSession = describeSession;
@@ -4902,7 +5219,9 @@ exports.mapActivityToHeuristicsEvent = mapActivityToEvent;
4902
5219
  exports.readSessionFromUrl = readSessionFromUrl;
4903
5220
  exports.registerCatalogBridge = registerCatalogBridge;
4904
5221
  exports.registerChartsBridge = registerChartsBridge;
5222
+ exports.registerCmsBridge = registerCmsBridge;
4905
5223
  exports.registerCodeBridge = registerCodeBridge;
5224
+ exports.registerDocBridge = registerDocBridge;
4906
5225
  exports.registerFeaturesBridge = registerFeaturesBridge;
4907
5226
  exports.registerFilesBridge = registerFilesBridge;
4908
5227
  exports.registerFormBridge = registerFormBridge;