@particle-academy/agent-integrations 0.50.0 → 0.52.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 (230) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/README.md +69 -0
  3. package/dist/bridges/artboard.d.cts +3 -3
  4. package/dist/bridges/artboard.d.ts +3 -3
  5. package/dist/bridges/catalog.d.cts +3 -3
  6. package/dist/bridges/catalog.d.ts +3 -3
  7. package/dist/bridges/charts.d.cts +3 -3
  8. package/dist/bridges/charts.d.ts +3 -3
  9. package/dist/bridges/cms.d.cts +3 -3
  10. package/dist/bridges/cms.d.ts +3 -3
  11. package/dist/bridges/code.d.cts +3 -3
  12. package/dist/bridges/code.d.ts +3 -3
  13. package/dist/bridges/doc.d.cts +3 -3
  14. package/dist/bridges/doc.d.ts +3 -3
  15. package/dist/bridges/features.d.cts +3 -3
  16. package/dist/bridges/features.d.ts +3 -3
  17. package/dist/bridges/files.d.cts +3 -3
  18. package/dist/bridges/files.d.ts +3 -3
  19. package/dist/bridges/flow.d.cts +3 -3
  20. package/dist/bridges/flow.d.ts +3 -3
  21. package/dist/bridges/forms.d.cts +55 -10
  22. package/dist/bridges/forms.d.ts +55 -10
  23. package/dist/bridges/git.d.cts +3 -3
  24. package/dist/bridges/git.d.ts +3 -3
  25. package/dist/bridges/grid.d.cts +3 -3
  26. package/dist/bridges/grid.d.ts +3 -3
  27. package/dist/bridges/map.d.cts +3 -3
  28. package/dist/bridges/map.d.ts +3 -3
  29. package/dist/bridges/navigation.d.cts +3 -3
  30. package/dist/bridges/navigation.d.ts +3 -3
  31. package/dist/bridges/passkeys.d.cts +3 -3
  32. package/dist/bridges/passkeys.d.ts +3 -3
  33. package/dist/bridges/scene.d.cts +3 -3
  34. package/dist/bridges/scene.d.ts +3 -3
  35. package/dist/bridges/screen-doc.d.cts +3 -3
  36. package/dist/bridges/screen-doc.d.ts +3 -3
  37. package/dist/bridges/screens.d.cts +3 -3
  38. package/dist/bridges/screens.d.ts +3 -3
  39. package/dist/bridges/sheets.d.cts +3 -3
  40. package/dist/bridges/sheets.d.ts +3 -3
  41. package/dist/bridges/slides.d.cts +3 -3
  42. package/dist/bridges/slides.d.ts +3 -3
  43. package/dist/bridges/terminal.d.cts +3 -3
  44. package/dist/bridges/terminal.d.ts +3 -3
  45. package/dist/bridges/tui.d.cts +2 -2
  46. package/dist/bridges/tui.d.ts +2 -2
  47. package/dist/bridges/whiteboard.d.cts +3 -3
  48. package/dist/bridges/whiteboard.d.ts +3 -3
  49. package/dist/bridges-artboard.cjs +11 -5
  50. package/dist/bridges-artboard.cjs.map +1 -1
  51. package/dist/bridges-artboard.js +6 -4
  52. package/dist/bridges-artboard.js.map +1 -1
  53. package/dist/bridges-catalog.cjs +11 -5
  54. package/dist/bridges-catalog.cjs.map +1 -1
  55. package/dist/bridges-catalog.js +3 -3
  56. package/dist/bridges-charts.cjs +11 -5
  57. package/dist/bridges-charts.cjs.map +1 -1
  58. package/dist/bridges-charts.js +3 -3
  59. package/dist/bridges-cms.cjs +11 -5
  60. package/dist/bridges-cms.cjs.map +1 -1
  61. package/dist/bridges-cms.js +4 -4
  62. package/dist/bridges-code.cjs +11 -5
  63. package/dist/bridges-code.cjs.map +1 -1
  64. package/dist/bridges-code.js +3 -3
  65. package/dist/bridges-doc.cjs +11 -5
  66. package/dist/bridges-doc.cjs.map +1 -1
  67. package/dist/bridges-doc.js +3 -3
  68. package/dist/bridges-features.cjs +11 -5
  69. package/dist/bridges-features.cjs.map +1 -1
  70. package/dist/bridges-features.js +3 -3
  71. package/dist/bridges-files.cjs +11 -5
  72. package/dist/bridges-files.cjs.map +1 -1
  73. package/dist/bridges-files.js +3 -3
  74. package/dist/bridges-flow.cjs +11 -5
  75. package/dist/bridges-flow.cjs.map +1 -1
  76. package/dist/bridges-flow.js +6 -4
  77. package/dist/bridges-flow.js.map +1 -1
  78. package/dist/bridges-forms.cjs +123 -16
  79. package/dist/bridges-forms.cjs.map +1 -1
  80. package/dist/bridges-forms.js +4 -3
  81. package/dist/bridges-git.cjs +10 -5
  82. package/dist/bridges-git.cjs.map +1 -1
  83. package/dist/bridges-git.js +3 -3
  84. package/dist/bridges-grid.cjs +11 -5
  85. package/dist/bridges-grid.cjs.map +1 -1
  86. package/dist/bridges-grid.js +3 -3
  87. package/dist/bridges-map.cjs +11 -5
  88. package/dist/bridges-map.cjs.map +1 -1
  89. package/dist/bridges-map.js +3 -3
  90. package/dist/bridges-navigation.cjs +11 -5
  91. package/dist/bridges-navigation.cjs.map +1 -1
  92. package/dist/bridges-navigation.js +3 -3
  93. package/dist/bridges-passkeys.cjs +11 -5
  94. package/dist/bridges-passkeys.cjs.map +1 -1
  95. package/dist/bridges-passkeys.js +3 -3
  96. package/dist/bridges-scene.cjs +11 -5
  97. package/dist/bridges-scene.cjs.map +1 -1
  98. package/dist/bridges-scene.js +3 -3
  99. package/dist/bridges-screen-doc.cjs +14 -6
  100. package/dist/bridges-screen-doc.cjs.map +1 -1
  101. package/dist/bridges-screen-doc.js +4 -4
  102. package/dist/bridges-screens.cjs +15 -7
  103. package/dist/bridges-screens.cjs.map +1 -1
  104. package/dist/bridges-screens.js +4 -3
  105. package/dist/bridges-sheets.cjs +11 -5
  106. package/dist/bridges-sheets.cjs.map +1 -1
  107. package/dist/bridges-sheets.js +3 -3
  108. package/dist/bridges-slides.cjs +11 -5
  109. package/dist/bridges-slides.cjs.map +1 -1
  110. package/dist/bridges-slides.js +3 -3
  111. package/dist/bridges-terminal.cjs +11 -5
  112. package/dist/bridges-terminal.cjs.map +1 -1
  113. package/dist/bridges-terminal.js +3 -3
  114. package/dist/bridges-tui.cjs +1 -1
  115. package/dist/bridges-tui.cjs.map +1 -1
  116. package/dist/bridges-tui.js +2 -2
  117. package/dist/bridges-whiteboard.cjs +11 -5
  118. package/dist/bridges-whiteboard.cjs.map +1 -1
  119. package/dist/bridges-whiteboard.js +3 -3
  120. package/dist/{chunk-CZV3WUW5.js → chunk-3GFKC6OK.js} +20 -7
  121. package/dist/chunk-3GFKC6OK.js.map +1 -0
  122. package/dist/{chunk-JLHVQWOV.js → chunk-6Q3PMT7K.js} +4 -4
  123. package/dist/chunk-6Q3PMT7K.js.map +1 -0
  124. package/dist/{chunk-HOZCDDRA.js → chunk-7HHZBPDE.js} +9 -29
  125. package/dist/chunk-7HHZBPDE.js.map +1 -0
  126. package/dist/{chunk-VFWFT3OK.js → chunk-AL77RO25.js} +97 -17
  127. package/dist/chunk-AL77RO25.js.map +1 -0
  128. package/dist/{chunk-AXWMWYH5.js → chunk-C4AQ2YBW.js} +7 -6
  129. package/dist/chunk-C4AQ2YBW.js.map +1 -0
  130. package/dist/{chunk-NH6HUVXQ.js → chunk-CI5ZVHDY.js} +8 -6
  131. package/dist/chunk-CI5ZVHDY.js.map +1 -0
  132. package/dist/{chunk-5ZWNCHZS.js → chunk-CKJL5C7A.js} +8 -6
  133. package/dist/chunk-CKJL5C7A.js.map +1 -0
  134. package/dist/chunk-DPBAEWB5.js +28 -0
  135. package/dist/chunk-DPBAEWB5.js.map +1 -0
  136. package/dist/{chunk-BG3QXNM6.js → chunk-HNVHAY4A.js} +8 -6
  137. package/dist/chunk-HNVHAY4A.js.map +1 -0
  138. package/dist/{chunk-5M5ELTHE.js → chunk-KAEPC6N4.js} +8 -6
  139. package/dist/chunk-KAEPC6N4.js.map +1 -0
  140. package/dist/{chunk-3WVXAB3D.js → chunk-M423JOQ3.js} +3 -3
  141. package/dist/{chunk-3WVXAB3D.js.map → chunk-M423JOQ3.js.map} +1 -1
  142. package/dist/{chunk-SWWJUOCY.js → chunk-MKC633WU.js} +3 -3
  143. package/dist/{chunk-SWWJUOCY.js.map → chunk-MKC633WU.js.map} +1 -1
  144. package/dist/{chunk-LQB42OSA.js → chunk-MKJE6V4Z.js} +8 -6
  145. package/dist/chunk-MKJE6V4Z.js.map +1 -0
  146. package/dist/{chunk-MIDZWKIF.js → chunk-NB5AQIR2.js} +8 -6
  147. package/dist/chunk-NB5AQIR2.js.map +1 -0
  148. package/dist/{chunk-VMRUW4B4.js → chunk-OUUHFR4N.js} +8 -6
  149. package/dist/chunk-OUUHFR4N.js.map +1 -0
  150. package/dist/{chunk-FCXSR7I5.js → chunk-P6SJBP5T.js} +8 -6
  151. package/dist/chunk-P6SJBP5T.js.map +1 -0
  152. package/dist/{chunk-5JLTXHX6.js → chunk-PMPBI6I3.js} +7 -5
  153. package/dist/chunk-PMPBI6I3.js.map +1 -0
  154. package/dist/{chunk-4WVLZ6YP.js → chunk-PV4FZDYX.js} +8 -6
  155. package/dist/chunk-PV4FZDYX.js.map +1 -0
  156. package/dist/{chunk-3UUF5KKZ.js → chunk-QEVSNDJW.js} +8 -6
  157. package/dist/chunk-QEVSNDJW.js.map +1 -0
  158. package/dist/{chunk-VOCUGTZB.js → chunk-S4DA2UTJ.js} +8 -6
  159. package/dist/chunk-S4DA2UTJ.js.map +1 -0
  160. package/dist/{chunk-RVMM4BHK.js → chunk-V6EHKHSF.js} +8 -6
  161. package/dist/chunk-V6EHKHSF.js.map +1 -0
  162. package/dist/{chunk-36MKPTVD.js → chunk-VE7TRWZR.js} +8 -6
  163. package/dist/chunk-VE7TRWZR.js.map +1 -0
  164. package/dist/{chunk-Z5NL5D4J.js → chunk-VFUKZ6UA.js} +8 -6
  165. package/dist/chunk-VFUKZ6UA.js.map +1 -0
  166. package/dist/{chunk-3HVYUMQF.js → chunk-VHB3VE53.js} +8 -6
  167. package/dist/chunk-VHB3VE53.js.map +1 -0
  168. package/dist/{chunk-R4XXOGQH.js → chunk-ZDKYKJFH.js} +10 -6
  169. package/dist/chunk-ZDKYKJFH.js.map +1 -0
  170. package/dist/components-shared-whiteboard.cjs +29 -10
  171. package/dist/components-shared-whiteboard.cjs.map +1 -1
  172. package/dist/components-shared-whiteboard.js +3 -3
  173. package/dist/dom-navigation/index.d.cts +3 -3
  174. package/dist/dom-navigation/index.d.ts +3 -3
  175. package/dist/index.cjs +211 -78
  176. package/dist/index.cjs.map +1 -1
  177. package/dist/index.d.cts +6 -6
  178. package/dist/index.d.ts +6 -6
  179. package/dist/index.js +27 -26
  180. package/dist/index.js.map +1 -1
  181. package/dist/mcp/index.d.cts +5 -5
  182. package/dist/mcp/index.d.ts +5 -5
  183. package/dist/mcp/stdio.d.cts +3 -3
  184. package/dist/mcp/stdio.d.ts +3 -3
  185. package/dist/mcp.cjs +18 -5
  186. package/dist/mcp.cjs.map +1 -1
  187. package/dist/mcp.js +1 -1
  188. package/dist/presence/index.d.cts +1 -1
  189. package/dist/presence/index.d.ts +1 -1
  190. package/dist/{server-1y0n61R5.d.cts → server-DJJygNo1.d.cts} +2 -2
  191. package/dist/{server-vq6qVl3T.d.ts → server-Dwo9LOxh.d.ts} +2 -2
  192. package/dist/sharing/index.d.cts +3 -3
  193. package/dist/sharing/index.d.ts +3 -3
  194. package/dist/sheets-adapter.d.cts +3 -3
  195. package/dist/sheets-adapter.d.ts +3 -3
  196. package/dist/{tool-host-LYfdPE8u.d.ts → tool-host-BBSaU7IJ.d.cts} +10 -4
  197. package/dist/{tool-host-D67N2a2h.d.cts → tool-host-BqJRPr_T.d.ts} +10 -4
  198. package/dist/{types-DP5yQZQU.d.cts → types-D_H2f-wF.d.cts} +1 -1
  199. package/dist/{types-VX_9je7w.d.ts → types-D_TzdBsK.d.ts} +1 -1
  200. package/dist/{types-gzIpsUDE.d.cts → types-ITRQFAir.d.cts} +26 -1
  201. package/dist/{types-gzIpsUDE.d.ts → types-ITRQFAir.d.ts} +26 -1
  202. package/dist/undo/index.d.cts +2 -2
  203. package/dist/undo/index.d.ts +2 -2
  204. package/dist/undo.cjs +7 -3
  205. package/dist/undo.cjs.map +1 -1
  206. package/dist/undo.js +3 -3
  207. package/docs/multi-form-hosts.md +97 -0
  208. package/package.json +1 -1
  209. package/dist/chunk-36MKPTVD.js.map +0 -1
  210. package/dist/chunk-3HVYUMQF.js.map +0 -1
  211. package/dist/chunk-3UUF5KKZ.js.map +0 -1
  212. package/dist/chunk-4WVLZ6YP.js.map +0 -1
  213. package/dist/chunk-5JLTXHX6.js.map +0 -1
  214. package/dist/chunk-5M5ELTHE.js.map +0 -1
  215. package/dist/chunk-5ZWNCHZS.js.map +0 -1
  216. package/dist/chunk-AXWMWYH5.js.map +0 -1
  217. package/dist/chunk-BG3QXNM6.js.map +0 -1
  218. package/dist/chunk-CZV3WUW5.js.map +0 -1
  219. package/dist/chunk-FCXSR7I5.js.map +0 -1
  220. package/dist/chunk-HOZCDDRA.js.map +0 -1
  221. package/dist/chunk-JLHVQWOV.js.map +0 -1
  222. package/dist/chunk-LQB42OSA.js.map +0 -1
  223. package/dist/chunk-MIDZWKIF.js.map +0 -1
  224. package/dist/chunk-NH6HUVXQ.js.map +0 -1
  225. package/dist/chunk-R4XXOGQH.js.map +0 -1
  226. package/dist/chunk-RVMM4BHK.js.map +0 -1
  227. package/dist/chunk-VFWFT3OK.js.map +0 -1
  228. package/dist/chunk-VMRUW4B4.js.map +0 -1
  229. package/dist/chunk-VOCUGTZB.js.map +0 -1
  230. package/dist/chunk-Z5NL5D4J.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -60,13 +60,23 @@ var ToolRegistry = class {
60
60
  */
61
61
  this.withdrawn = /* @__PURE__ */ new Set();
62
62
  }
63
- registerTool(definition, handler) {
64
- this.tools.set(definition.name, { definition, handler });
65
- this.withdrawn.delete(definition.name);
63
+ registerTool(definition, handler, options = {}) {
64
+ const name = definition.name;
65
+ const { owner, replace = false } = options;
66
+ const held = this.tools.get(name);
67
+ if (held && !replace && (owner === void 0 || held.owner !== owner)) {
68
+ throw new Error(
69
+ `Tool "${name}" is already registered by ${describeOwner(held.owner)}; ${describeOwner(owner)} cannot register it too. Two registrants for one name would leave the first one listed but unreachable. Give one of them a different tool name, dispose the first registration, or pass { replace: true } to take the name over deliberately.`
70
+ );
71
+ }
72
+ const record = owner === void 0 ? { definition, handler } : { definition, handler, owner };
73
+ this.tools.set(name, record);
74
+ this.withdrawn.delete(name);
66
75
  this.onToolsChanged();
67
76
  return () => {
68
- if (this.tools.delete(definition.name)) {
69
- this.withdrawn.add(definition.name);
77
+ if (this.tools.get(name) === record) {
78
+ this.tools.delete(name);
79
+ this.withdrawn.add(name);
70
80
  this.onToolsChanged();
71
81
  }
72
82
  };
@@ -95,6 +105,9 @@ var ToolRegistry = class {
95
105
  onToolsChanged() {
96
106
  }
97
107
  };
108
+ function describeOwner(owner) {
109
+ return owner === void 0 ? "an unnamed registrant (pass { owner } to registerTool to identify it)" : `"${owner}"`;
110
+ }
98
111
 
99
112
  // src/mcp/server.ts
100
113
  var MicroMcpServer = class extends ToolRegistry {
@@ -434,7 +447,7 @@ function registerTuiBridge(host, options) {
434
447
  } catch (error) {
435
448
  return errorResult(error instanceof Error ? error.message : String(error));
436
449
  }
437
- }));
450
+ }, { owner: "tui" }));
438
451
  };
439
452
  const publish = async (surfaceId, type, payload, actor = defaultActor, priority = "normal") => options.eventStore.append({ appId: options.appId, sessionId: options.sessionId, surfaceId, type, payload, actor, priority });
440
453
  register("tui_surfaces_list", "List addressable Fancy TUI surfaces and commands.", {}, [], () => options.registry.list().map((surface) => ({ id: surface.id, kind: surface.kind, label: surface.label, commands: surface.commands?.map((command) => ({ name: command.name, description: command.description, policy: command.policy ?? "execute", inputSchema: command.inputSchema })) ?? [] })));
@@ -514,6 +527,7 @@ function registerTuiBridge(host, options) {
514
527
 
515
528
  // src/undo/undo-tools.ts
516
529
  var installedHosts = /* @__PURE__ */ new WeakSet();
530
+ var UNDO_TOOLS_OWNER = "agent-undo";
517
531
  function ensureUndoToolsRegistered(host, options = {}) {
518
532
  if (installedHosts.has(host)) return;
519
533
  installedHosts.add(host);
@@ -538,7 +552,8 @@ function registerUndoTools(host, options = {}) {
538
552
  const entry = await fancyAutoCommon.undoOne(agentOf(args));
539
553
  if (!entry) return errorResult("Nothing to undo.");
540
554
  return textResult(`Undid: ${entry.label}`, { entry: serialize(entry) });
541
- }
555
+ },
556
+ { owner: UNDO_TOOLS_OWNER }
542
557
  )
543
558
  );
544
559
  disposers.push(
@@ -556,7 +571,8 @@ function registerUndoTools(host, options = {}) {
556
571
  const entry = await fancyAutoCommon.redoOne(agentOf(args));
557
572
  if (!entry) return errorResult("Nothing to redo.");
558
573
  return textResult(`Redid: ${entry.label}`, { entry: serialize(entry) });
559
- }
574
+ },
575
+ { owner: UNDO_TOOLS_OWNER }
560
576
  )
561
577
  );
562
578
  disposers.push(
@@ -574,7 +590,8 @@ function registerUndoTools(host, options = {}) {
574
590
  const history = fancyAutoCommon.readHistory(agentOf(args)).map(serialize);
575
591
  const text = history.map((e) => `${new Date(e.timestamp).toISOString()} ${e.bridgeId} ${e.action}: ${e.label}`).join("\n");
576
592
  return textResult(text || "(empty)", history);
577
- }
593
+ },
594
+ { owner: UNDO_TOOLS_OWNER }
578
595
  )
579
596
  );
580
597
  return () => disposers.forEach((d) => d());
@@ -588,6 +605,34 @@ function serialize(entry) {
588
605
  };
589
606
  }
590
607
 
608
+ // src/bridges/forms.ts
609
+ init_registry();
610
+
611
+ // src/bridges/host-commit.ts
612
+ function hostErrorMessage(e, fallback) {
613
+ let msg;
614
+ if (e instanceof Error) msg = e.message;
615
+ else if (typeof e === "string") msg = e;
616
+ else if (e && typeof e === "object" && typeof e.message === "string") {
617
+ msg = e.message;
618
+ }
619
+ const firstFrame = msg ? msg.search(/\n\s+at\s/) : -1;
620
+ if (msg && firstFrame >= 0) msg = msg.slice(0, firstFrame);
621
+ msg = msg?.trim();
622
+ return msg ? msg : fallback;
623
+ }
624
+ async function commit(run, fallback) {
625
+ try {
626
+ const r = await run();
627
+ if (r && typeof r === "object" && r.ok === false) {
628
+ return { ok: false, error: hostErrorMessage(r.error, fallback) };
629
+ }
630
+ return { ok: true };
631
+ } catch (e) {
632
+ return { ok: false, error: hostErrorMessage(e, fallback) };
633
+ }
634
+ }
635
+
591
636
  // src/bridges/forms.ts
592
637
  var DEFAULT_AGENT = { id: "agent", name: "Agent", color: "#a855f7" };
593
638
  function registerFormBridge(host, options) {
@@ -595,8 +640,36 @@ function registerFormBridge(host, options) {
595
640
  const agent = { ...DEFAULT_AGENT, ...options.agent ?? {} };
596
641
  const pendingMode = options.pendingMode ?? true;
597
642
  const disposers = [];
643
+ const bridgeId = `form:${adapter.id}`;
598
644
  ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
599
645
  const formId = adapter.id;
646
+ let disposed = false;
647
+ const onDispose = /* @__PURE__ */ new Set();
648
+ const CLOSED = /* @__PURE__ */ Symbol("form-closed");
649
+ const untilClosed = (p) => {
650
+ if (disposed) {
651
+ p.catch(() => {
652
+ });
653
+ return Promise.resolve(CLOSED);
654
+ }
655
+ return new Promise((resolve, reject) => {
656
+ const close = () => resolve(CLOSED);
657
+ onDispose.add(close);
658
+ p.then(
659
+ (v) => {
660
+ onDispose.delete(close);
661
+ resolve(v);
662
+ },
663
+ (e) => {
664
+ onDispose.delete(close);
665
+ reject(e);
666
+ }
667
+ );
668
+ });
669
+ };
670
+ const closedUnknown = (what) => errorResult(
671
+ `Form "${formId}" was closed before the host confirmed ${what}, so whether it was applied is unknown. Do not assume it was. If the form is open again, read it back (form_get_values) before retrying.`
672
+ );
600
673
  const target = (args) => ({
601
674
  kind: "form",
602
675
  screenId: adapter.screenId,
@@ -608,7 +681,7 @@ function registerFormBridge(host, options) {
608
681
  try {
609
682
  return await handler(args);
610
683
  } catch (e) {
611
- return errorResult(e instanceof Error ? e.message : String(e));
684
+ return errorResult(hostErrorMessage(e, `${name} failed.`));
612
685
  }
613
686
  };
614
687
  const final = isMutation ? wrapToolWithActivity(wrapped, {
@@ -625,7 +698,8 @@ function registerFormBridge(host, options) {
625
698
  description,
626
699
  inputSchema: { type: "object", properties, required, additionalProperties: false }
627
700
  },
628
- final
701
+ final,
702
+ { owner: bridgeId }
629
703
  )
630
704
  );
631
705
  };
@@ -675,11 +749,15 @@ function registerFormBridge(host, options) {
675
749
  value: { description: "Value to set. Type depends on the field's `type`." }
676
750
  },
677
751
  ["field", "value"],
678
- (args) => {
752
+ async (args) => {
679
753
  const name = String(args.field ?? "");
680
754
  const fieldDef = adapter.getFields().find((f) => f.name === name);
681
755
  if (!fieldDef) return errorResult(`Unknown field: ${name}`);
682
- adapter.setValue(name, args.value);
756
+ const done = await untilClosed(
757
+ commit(() => adapter.setValue(name, args.value), `Host refused the write to "${name}".`)
758
+ );
759
+ if (done === CLOSED) return closedUnknown(`the write to "${name}"`);
760
+ if (!done.ok) return errorResult(done.error);
683
761
  return textResult(`${name} \u2190 ${JSON.stringify(args.value)}`, { field: name, value: args.value });
684
762
  },
685
763
  true
@@ -689,16 +767,52 @@ function registerFormBridge(host, options) {
689
767
  "Set multiple fields atomically. Pass a `values` object keyed by field name.",
690
768
  { values: { type: "object" } },
691
769
  ["values"],
692
- (args) => {
770
+ async (args) => {
693
771
  const values = args.values && typeof args.values === "object" ? args.values : {};
694
772
  const fields = adapter.getFields();
695
773
  const known = new Set(fields.map((f) => f.name));
696
774
  const unknownKeys = Object.keys(values).filter((k) => !known.has(k));
697
775
  if (unknownKeys.length) return errorResult(`Unknown fields: ${unknownKeys.join(", ")}`);
698
- if (adapter.setValues) {
699
- adapter.setValues(values);
776
+ const setValues = adapter.setValues;
777
+ if (setValues) {
778
+ const done = await untilClosed(commit(() => setValues(values), "Host refused the write."));
779
+ if (done === CLOSED) return closedUnknown("the write");
780
+ if (!done.ok) return errorResult(done.error);
700
781
  } else {
701
- for (const [k, v] of Object.entries(values)) adapter.setValue(k, v);
782
+ const keys = Object.keys(values);
783
+ const committed = [];
784
+ for (const [i, k] of keys.entries()) {
785
+ const done = await untilClosed(
786
+ commit(() => adapter.setValue(k, values[k]), `Host refused the write to "${k}".`)
787
+ );
788
+ if (done === CLOSED) {
789
+ return {
790
+ ...closedUnknown(`the write to "${k}"`),
791
+ structuredContent: { committed, pending: k, notAttempted: keys.slice(i + 1) }
792
+ };
793
+ }
794
+ if (!done.ok) {
795
+ const state = { committed, failed: k, notAttempted: keys.slice(i + 1) };
796
+ if (committed.length) {
797
+ fancyAutoCommon.emitActivity({
798
+ agentId: agent.id,
799
+ agentName: agent.name,
800
+ agentColor: agent.color,
801
+ target: target({}),
802
+ action: "form_set_values",
803
+ timestamp: Date.now(),
804
+ meta: state
805
+ });
806
+ }
807
+ return {
808
+ ...errorResult(
809
+ `"${k}" was refused: ${done.error} ` + (committed.length ? `Already committed and NOT rolled back: ${committed.join(", ")}. ` : "Nothing was committed. ") + (state.notAttempted.length ? `Not attempted: ${state.notAttempted.join(", ")}.` : "")
810
+ ),
811
+ structuredContent: state
812
+ };
813
+ }
814
+ committed.push(k);
815
+ }
702
816
  }
703
817
  return textResult(`Set ${Object.keys(values).length} field(s)`, { values });
704
818
  },
@@ -728,25 +842,34 @@ function registerFormBridge(host, options) {
728
842
  async () => {
729
843
  if (!adapter.submit) return errorResult("Host did not provide a submit implementation.");
730
844
  if (pendingMode && adapter.confirm) {
731
- const ok = await adapter.confirm({
845
+ const confirm = adapter.confirm;
846
+ const ok = await untilClosed(Promise.resolve().then(() => confirm({
732
847
  action: "submit",
733
848
  form: formId,
734
849
  title: adapter.title,
735
850
  values: adapter.getValues()
736
- });
851
+ })));
852
+ if (ok === CLOSED) {
853
+ return errorResult(`Form "${formId}" was closed before the submit was confirmed. Nothing was submitted.`);
854
+ }
737
855
  if (!ok) return errorResult("Declined by user");
738
856
  }
739
- const result = await adapter.submit();
740
- if (!result.ok) return errorResult(result.error ?? "Submit failed");
857
+ const submit = adapter.submit;
858
+ const result = await untilClosed(Promise.resolve().then(() => submit()));
859
+ if (result === CLOSED) return closedUnknown("the submit");
860
+ if (!result.ok) return errorResult(hostErrorMessage(result.error, "Submit failed"));
741
861
  return textResult("Submitted", { values: result.values });
742
862
  },
743
863
  true
744
864
  );
745
865
  return {
746
- id: `form:${formId}`,
866
+ id: bridgeId,
747
867
  title: adapter.title ?? formId,
748
868
  dispose: () => {
869
+ disposed = true;
749
870
  for (const d of disposers) d();
871
+ for (const close of [...onDispose]) close();
872
+ onDispose.clear();
750
873
  }
751
874
  };
752
875
  }
@@ -757,6 +880,7 @@ function registerSheetsBridge(host, options) {
757
880
  const { adapter } = options;
758
881
  const agent = { ...DEFAULT_AGENT2, ...options.agent ?? {} };
759
882
  const disposers = [];
883
+ const bridgeId = "sheets";
760
884
  ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
761
885
  const target = (sheetId, address) => ({
762
886
  kind: "sheet",
@@ -786,7 +910,8 @@ function registerSheetsBridge(host, options) {
786
910
  description,
787
911
  inputSchema: { type: "object", properties, required, additionalProperties: false }
788
912
  },
789
- final
913
+ final,
914
+ { owner: bridgeId }
790
915
  )
791
916
  );
792
917
  };
@@ -966,7 +1091,7 @@ function registerSheetsBridge(host, options) {
966
1091
  (args) => target(getSheetId(args), String(args.address ?? ""))
967
1092
  );
968
1093
  return {
969
- id: "sheets",
1094
+ id: bridgeId,
970
1095
  title: "Sheets",
971
1096
  dispose: () => {
972
1097
  for (const d of disposers) d();
@@ -1105,6 +1230,7 @@ function registerCodeBridge(host, options) {
1105
1230
  const { adapter } = options;
1106
1231
  const agent = { ...DEFAULT_AGENT3, ...options.agent ?? {} };
1107
1232
  const disposers = [];
1233
+ const bridgeId = `code:${adapter.id}`;
1108
1234
  ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
1109
1235
  const target = {
1110
1236
  kind: "code",
@@ -1144,7 +1270,8 @@ function registerCodeBridge(host, options) {
1144
1270
  description,
1145
1271
  inputSchema: { type: "object", properties, required, additionalProperties: false }
1146
1272
  },
1147
- final
1273
+ final,
1274
+ { owner: bridgeId }
1148
1275
  )
1149
1276
  );
1150
1277
  };
@@ -1292,7 +1419,7 @@ function registerCodeBridge(host, options) {
1292
1419
  false
1293
1420
  );
1294
1421
  return {
1295
- id: `code:${adapter.id}`,
1422
+ id: bridgeId,
1296
1423
  title: adapter.title ?? adapter.id,
1297
1424
  dispose: () => {
1298
1425
  for (const d of disposers) d();
@@ -1306,6 +1433,7 @@ function registerChartsBridge(host, options) {
1306
1433
  const { adapter } = options;
1307
1434
  const agent = { ...DEFAULT_AGENT4, ...options.agent ?? {} };
1308
1435
  const disposers = [];
1436
+ const bridgeId = `chart:${adapter.id}`;
1309
1437
  ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
1310
1438
  const target = {
1311
1439
  kind: "chart",
@@ -1331,7 +1459,8 @@ function registerChartsBridge(host, options) {
1331
1459
  disposers.push(
1332
1460
  host.registerTool(
1333
1461
  { name, description, inputSchema: { type: "object", properties, required, additionalProperties: false } },
1334
- final
1462
+ final,
1463
+ { owner: bridgeId }
1335
1464
  )
1336
1465
  );
1337
1466
  };
@@ -1407,7 +1536,7 @@ function registerChartsBridge(host, options) {
1407
1536
  true
1408
1537
  );
1409
1538
  return {
1410
- id: `chart:${adapter.id}`,
1539
+ id: bridgeId,
1411
1540
  title: adapter.title ?? adapter.id,
1412
1541
  dispose: () => {
1413
1542
  for (const d of disposers) d();
@@ -1421,6 +1550,7 @@ function registerGridBridge(host, options) {
1421
1550
  const { adapter } = options;
1422
1551
  const agent = { ...DEFAULT_AGENT5, ...options.agent ?? {} };
1423
1552
  const disposers = [];
1553
+ const bridgeId = `grid:${adapter.id}`;
1424
1554
  ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
1425
1555
  const target = (part) => ({
1426
1556
  kind: "grid",
@@ -1450,7 +1580,8 @@ function registerGridBridge(host, options) {
1450
1580
  description,
1451
1581
  inputSchema: { type: "object", properties, required, additionalProperties: false }
1452
1582
  },
1453
- final
1583
+ final,
1584
+ { owner: bridgeId }
1454
1585
  )
1455
1586
  );
1456
1587
  };
@@ -1608,7 +1739,7 @@ function registerGridBridge(host, options) {
1608
1739
  );
1609
1740
  }
1610
1741
  return {
1611
- id: `grid:${adapter.id}`,
1742
+ id: bridgeId,
1612
1743
  title: adapter.title ?? adapter.id,
1613
1744
  dispose: () => {
1614
1745
  for (const d of disposers) d();
@@ -1623,6 +1754,7 @@ function registerSceneBridge(host, options) {
1623
1754
  const { adapter } = options;
1624
1755
  const agent = { ...DEFAULT_AGENT6, ...options.agent ?? {} };
1625
1756
  const disposers = [];
1757
+ const bridgeId = `scene:${adapter.id}`;
1626
1758
  ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
1627
1759
  const target = (objectId) => ({
1628
1760
  kind: "scene",
@@ -1648,7 +1780,8 @@ function registerSceneBridge(host, options) {
1648
1780
  disposers.push(
1649
1781
  host.registerTool(
1650
1782
  { name, description, inputSchema: { type: "object", properties, required, additionalProperties: false } },
1651
- final
1783
+ final,
1784
+ { owner: bridgeId }
1652
1785
  )
1653
1786
  );
1654
1787
  };
@@ -1801,7 +1934,7 @@ function registerSceneBridge(host, options) {
1801
1934
  true
1802
1935
  );
1803
1936
  return {
1804
- id: `scene:${adapter.id}`,
1937
+ id: bridgeId,
1805
1938
  title: adapter.title ?? adapter.id,
1806
1939
  dispose: () => {
1807
1940
  for (const d of disposers) d();
@@ -1818,33 +1951,11 @@ function parseTriple(v) {
1818
1951
  // src/bridges/screens.ts
1819
1952
  init_registry();
1820
1953
  var DEFAULT_AGENT7 = { id: "agent", name: "Agent", color: "#a855f7" };
1821
- function hostErrorMessage(e, fallback) {
1822
- let msg;
1823
- if (e instanceof Error) msg = e.message;
1824
- else if (typeof e === "string") msg = e;
1825
- else if (e && typeof e === "object" && typeof e.message === "string") {
1826
- msg = e.message;
1827
- }
1828
- const firstFrame = msg ? msg.search(/\n\s+at\s/) : -1;
1829
- if (msg && firstFrame >= 0) msg = msg.slice(0, firstFrame);
1830
- msg = msg?.trim();
1831
- return msg ? msg : fallback;
1832
- }
1833
- async function commit(run, fallback) {
1834
- try {
1835
- const r = await run();
1836
- if (r && typeof r === "object" && r.ok === false) {
1837
- return { ok: false, error: hostErrorMessage(r.error, fallback) };
1838
- }
1839
- return { ok: true };
1840
- } catch (e) {
1841
- return { ok: false, error: hostErrorMessage(e, fallback) };
1842
- }
1843
- }
1844
1954
  function registerScreensBridge(host, options) {
1845
1955
  const { adapter } = options;
1846
1956
  const agent = { ...DEFAULT_AGENT7, ...options.agent ?? {} };
1847
1957
  const disposers = [];
1958
+ const bridgeId = "screens";
1848
1959
  ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
1849
1960
  const target = (screenId) => ({
1850
1961
  kind: "screens",
@@ -1868,7 +1979,8 @@ function registerScreensBridge(host, options) {
1868
1979
  disposers.push(
1869
1980
  host.registerTool(
1870
1981
  { name, description, inputSchema: { type: "object", properties, required, additionalProperties: false } },
1871
- final
1982
+ final,
1983
+ { owner: bridgeId }
1872
1984
  )
1873
1985
  );
1874
1986
  };
@@ -2037,7 +2149,7 @@ function registerScreensBridge(host, options) {
2037
2149
  (args) => target(String(args.screen ?? ""))
2038
2150
  );
2039
2151
  return {
2040
- id: "screens",
2152
+ id: bridgeId,
2041
2153
  title: "Screens",
2042
2154
  dispose: () => {
2043
2155
  for (const d of disposers) d();
@@ -2051,6 +2163,7 @@ function registerSlidesBridge(host, options) {
2051
2163
  const { adapter } = options;
2052
2164
  const agent = { ...DEFAULT_AGENT8, ...options.agent ?? {} };
2053
2165
  const disposers = [];
2166
+ const bridgeId = "slides";
2054
2167
  ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
2055
2168
  const deckTarget = () => ({
2056
2169
  kind: "deck",
@@ -2097,7 +2210,8 @@ function registerSlidesBridge(host, options) {
2097
2210
  additionalProperties: false
2098
2211
  }
2099
2212
  },
2100
- final
2213
+ final,
2214
+ { owner: bridgeId }
2101
2215
  )
2102
2216
  );
2103
2217
  };
@@ -2462,7 +2576,7 @@ function registerSlidesBridge(host, options) {
2462
2576
  (args) => elementTarget(str(args?.slideId), str(args?.elementId))
2463
2577
  );
2464
2578
  return {
2465
- id: "slides",
2579
+ id: bridgeId,
2466
2580
  title: "Slides",
2467
2581
  dispose: () => {
2468
2582
  for (const d of disposers.splice(0)) d();
@@ -2497,6 +2611,7 @@ function registerMapBridge(host, options) {
2497
2611
  const { adapter } = options;
2498
2612
  const agent = { ...DEFAULT_AGENT9, ...options.agent ?? {} };
2499
2613
  const disposers = [];
2614
+ const bridgeId = "map";
2500
2615
  ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
2501
2616
  const mTarget = (args, result) => ({
2502
2617
  kind: "map",
@@ -2528,7 +2643,8 @@ function registerMapBridge(host, options) {
2528
2643
  additionalProperties: false
2529
2644
  }
2530
2645
  },
2531
- final
2646
+ final,
2647
+ { owner: bridgeId }
2532
2648
  )
2533
2649
  );
2534
2650
  };
@@ -2807,7 +2923,7 @@ function registerMapBridge(host, options) {
2807
2923
  }
2808
2924
  );
2809
2925
  return {
2810
- id: "map",
2926
+ id: bridgeId,
2811
2927
  title: "Map",
2812
2928
  dispose: () => {
2813
2929
  for (const d of disposers) d();
@@ -2819,6 +2935,7 @@ function registerMapBridge(host, options) {
2819
2935
  function registerGitBridge(host, options) {
2820
2936
  const agent = { id: "agent", name: "Agent", color: "#a855f7", ...options.agent ?? {} };
2821
2937
  const disposers = [];
2938
+ const bridgeId = "git";
2822
2939
  ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
2823
2940
  const reg = (name, description, properties, required, handler, mutation2 = false) => {
2824
2941
  const wrapped = async (args) => {
@@ -2838,7 +2955,7 @@ function registerGitBridge(host, options) {
2838
2955
  name,
2839
2956
  description,
2840
2957
  inputSchema: { type: "object", properties, required, additionalProperties: false }
2841
- }, final));
2958
+ }, final, { owner: bridgeId }));
2842
2959
  };
2843
2960
  reg("git_status", "Read normalized working-tree and branch status.", {}, [], async () => {
2844
2961
  const result = await options.adapter.status();
@@ -2899,7 +3016,7 @@ function registerGitBridge(host, options) {
2899
3016
  draft: { type: "boolean" },
2900
3017
  apply: { type: "boolean" }
2901
3018
  }, ["title", "sourceBranch", "targetBranch"]);
2902
- return { id: "git", title: "Git", dispose: () => disposers.forEach((dispose) => dispose()) };
3019
+ return { id: bridgeId, title: "Git", dispose: () => disposers.forEach((dispose) => dispose()) };
2903
3020
  }
2904
3021
 
2905
3022
  // src/bridges/files.ts
@@ -2943,6 +3060,7 @@ function registerFilesBridge(host, options) {
2943
3060
  const agent = { ...DEFAULT_AGENT10, ...options.agent ?? {} };
2944
3061
  const pendingMode = options.pendingMode ?? true;
2945
3062
  const disposers = [];
3063
+ const bridgeId = "files";
2946
3064
  const guard = (path) => {
2947
3065
  if (options.root !== void 0) assertPathWithinRoot(options.root, path);
2948
3066
  return path;
@@ -2978,7 +3096,8 @@ function registerFilesBridge(host, options) {
2978
3096
  additionalProperties: false
2979
3097
  }
2980
3098
  },
2981
- final
3099
+ final,
3100
+ { owner: bridgeId }
2982
3101
  )
2983
3102
  );
2984
3103
  };
@@ -3168,7 +3287,7 @@ function registerFilesBridge(host, options) {
3168
3287
  fTarget
3169
3288
  );
3170
3289
  return {
3171
- id: "files",
3290
+ id: bridgeId,
3172
3291
  title: "Files",
3173
3292
  dispose: () => {
3174
3293
  for (const d of disposers) d();
@@ -3184,6 +3303,7 @@ function registerTerminalBridge(host, options) {
3184
3303
  const pendingMode = options.pendingMode ?? true;
3185
3304
  const screenId = options.screenId ?? options.adapter?.screenId;
3186
3305
  const disposers = [];
3306
+ const bridgeId = "terminal";
3187
3307
  const staged = /* @__PURE__ */ new Map();
3188
3308
  let seq = 0;
3189
3309
  ensureUndoToolsRegistered(host);
@@ -3250,7 +3370,8 @@ function registerTerminalBridge(host, options) {
3250
3370
  description,
3251
3371
  inputSchema: { type: "object", properties, required, additionalProperties: false }
3252
3372
  },
3253
- final
3373
+ final,
3374
+ { owner: bridgeId }
3254
3375
  )
3255
3376
  );
3256
3377
  };
@@ -3447,7 +3568,7 @@ function registerTerminalBridge(host, options) {
3447
3568
  );
3448
3569
  }
3449
3570
  return {
3450
- id: "terminal",
3571
+ id: bridgeId,
3451
3572
  title: "Terminal",
3452
3573
  dispose: () => {
3453
3574
  disposers.forEach((d) => d());
@@ -3492,6 +3613,7 @@ function registerNavigationBridge(host, options) {
3492
3613
  const agent = { ...DEFAULT_AGENT12, ...options.agent ?? {} };
3493
3614
  const pendingMode = options.pendingMode ?? true;
3494
3615
  const disposers = [];
3616
+ const bridgeId = "navigation";
3495
3617
  let groundedRevision = null;
3496
3618
  const staleIntent = async () => {
3497
3619
  const current = await adapter.getRevision?.();
@@ -3535,7 +3657,8 @@ function registerNavigationBridge(host, options) {
3535
3657
  description,
3536
3658
  inputSchema: { type: "object", properties, required, additionalProperties: false }
3537
3659
  },
3538
- final
3660
+ final,
3661
+ { owner: bridgeId }
3539
3662
  )
3540
3663
  );
3541
3664
  };
@@ -3771,7 +3894,7 @@ function registerNavigationBridge(host, options) {
3771
3894
  (args) => target(`Submit ${String(args.handle ?? "")}`, String(args.handle ?? ""))
3772
3895
  );
3773
3896
  return {
3774
- id: "navigation",
3897
+ id: bridgeId,
3775
3898
  title: "Co-browsing",
3776
3899
  dispose: () => {
3777
3900
  for (const d of disposers) d();
@@ -3789,6 +3912,7 @@ function registerCatalogBridge(host, options) {
3789
3912
  const pendingMode = options.pendingMode ?? true;
3790
3913
  const catalogId = adapter.id ?? "catalog";
3791
3914
  const disposers = [];
3915
+ const bridgeId = `catalog:${catalogId}`;
3792
3916
  ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
3793
3917
  const target = (elementId, label) => ({
3794
3918
  kind: "custom",
@@ -3814,7 +3938,8 @@ function registerCatalogBridge(host, options) {
3814
3938
  disposers.push(
3815
3939
  host.registerTool(
3816
3940
  { name, description, inputSchema: { type: "object", properties, required, additionalProperties: false } },
3817
- final
3941
+ final,
3942
+ { owner: bridgeId }
3818
3943
  )
3819
3944
  );
3820
3945
  };
@@ -4088,7 +4213,7 @@ function registerCatalogBridge(host, options) {
4088
4213
  (args) => target(str4(args.priceId), `checkout ${str4(args.priceId)}`)
4089
4214
  );
4090
4215
  return {
4091
- id: `catalog:${catalogId}`,
4216
+ id: bridgeId,
4092
4217
  title: adapter.title ?? "Catalog",
4093
4218
  dispose: () => {
4094
4219
  for (const d of disposers.splice(0)) d();
@@ -4106,6 +4231,7 @@ function registerFeaturesBridge(host, options) {
4106
4231
  const pendingMode = options.pendingMode ?? true;
4107
4232
  const featuresId = adapter.id ?? "features";
4108
4233
  const disposers = [];
4234
+ const bridgeId = `features:${featuresId}`;
4109
4235
  ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
4110
4236
  const target = (elementId, label) => ({
4111
4237
  kind: "custom",
@@ -4131,7 +4257,8 @@ function registerFeaturesBridge(host, options) {
4131
4257
  disposers.push(
4132
4258
  host.registerTool(
4133
4259
  { name, description, inputSchema: { type: "object", properties, required, additionalProperties: false } },
4134
- final
4260
+ final,
4261
+ { owner: bridgeId }
4135
4262
  )
4136
4263
  );
4137
4264
  };
@@ -4306,7 +4433,7 @@ function registerFeaturesBridge(host, options) {
4306
4433
  (args) => target(str5(args.feature), `consume ${str5(args.feature)}`)
4307
4434
  );
4308
4435
  return {
4309
- id: `features:${featuresId}`,
4436
+ id: bridgeId,
4310
4437
  title: adapter.title ?? "Features",
4311
4438
  dispose: () => {
4312
4439
  for (const d of disposers.splice(0)) d();
@@ -4341,6 +4468,7 @@ function registerPasskeyBridge(host, options) {
4341
4468
  const agent = { ...DEFAULT_AGENT15, ...options.agent ?? {} };
4342
4469
  const surfaceId = adapter.id ?? "passkeys";
4343
4470
  const disposers = [];
4471
+ const bridgeId = `passkeys:${surfaceId}`;
4344
4472
  ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
4345
4473
  const target = (elementId, label) => ({
4346
4474
  kind: "custom",
@@ -4375,7 +4503,8 @@ function registerPasskeyBridge(host, options) {
4375
4503
  additionalProperties: false
4376
4504
  }
4377
4505
  },
4378
- final
4506
+ final,
4507
+ { owner: bridgeId }
4379
4508
  )
4380
4509
  );
4381
4510
  };
@@ -4496,7 +4625,7 @@ function registerPasskeyBridge(host, options) {
4496
4625
  (args) => target(void 0, `begin enrollment${args.name ? ` (${str6(args.name)})` : ""}`)
4497
4626
  );
4498
4627
  return {
4499
- id: `passkeys:${surfaceId}`,
4628
+ id: bridgeId,
4500
4629
  title: adapter.title ?? "Passkeys",
4501
4630
  dispose: () => {
4502
4631
  for (const d of disposers.splice(0)) d();
@@ -4512,6 +4641,7 @@ function registerDocBridge(host, options) {
4512
4641
  const makeNode = options.makeNode ?? (({ id, type, parent, order }, props) => ({ id, type, parent, order, props }));
4513
4642
  const describeNode = options.describeNode ?? ((n) => ({ id: n.id, type: n.type, parent: n.parent, props: Object.keys(n.props ?? {}) }));
4514
4643
  const disposers = [];
4644
+ const bridgeId = surface;
4515
4645
  ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });
4516
4646
  let idSeq = 0;
4517
4647
  const mintId = () => {
@@ -4572,7 +4702,8 @@ function registerDocBridge(host, options) {
4572
4702
  disposers.push(
4573
4703
  host.registerTool(
4574
4704
  { name, description, inputSchema: { type: "object", properties, required, additionalProperties: false } },
4575
- final
4705
+ final,
4706
+ { owner: bridgeId }
4576
4707
  )
4577
4708
  );
4578
4709
  };
@@ -4747,7 +4878,7 @@ function registerDocBridge(host, options) {
4747
4878
  false
4748
4879
  );
4749
4880
  return {
4750
- id: surface,
4881
+ id: bridgeId,
4751
4882
  title: surface,
4752
4883
  dispose: () => {
4753
4884
  for (const d of disposers) d();
@@ -4900,7 +5031,9 @@ function registerScreenDocBridge(host, options) {
4900
5031
  authored.length ? `${authored.length} addressable, ${syntheticCount} positional` : `no addressable ids \u2014 all ${syntheticCount} nodes are positional`,
4901
5032
  { addressable: authored, syntheticCount }
4902
5033
  );
4903
- })
5034
+ }),
5035
+ // Same registrant as the doc bridge above, which registers under its surface.
5036
+ { owner: surface }
4904
5037
  );
4905
5038
  return {
4906
5039
  id: surface,